From bbfab1063adc3039bcbf2bc0028e0a68084a6966 Mon Sep 17 00:00:00 2001 From: Ayu Date: Sun, 2 Feb 2025 04:17:27 +0800 Subject: [PATCH 01/43] renamed chatbot Duke to Sparkle changed logo renamed filename --- src/main/java/Duke.java | 10 --------- src/main/java/Sparkle.java | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 10 deletions(-) delete mode 100644 src/main/java/Duke.java create mode 100644 src/main/java/Sparkle.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334c..000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java new file mode 100644 index 000000000..6af1511fa --- /dev/null +++ b/src/main/java/Sparkle.java @@ -0,0 +1,46 @@ +public class Sparkle { + public static void main(String[] args) { + String logo = "QQQQQQQNggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggNQQQQQQQ\n"+ +"QQQQQNNHiiLL777cc7cuIsFfIIYjeziijzjjFsurrrrrrrrrrrrrrTLTirrrr111|||vi7IzIzFoS4jJxllIIfYFFFfvpNNQQQQQ\n"+ +"QQQQNM8lLTttttttttcy5AaaA22o2a5SEPkPj-mT^^^^^^^^^^^^v^--^vr^^^^rrvTFyoZGekkkBBbk4ZwXPkkEE962t8MNNQQQ\n"+ +"QQNMbAcLcLiivv||rrr^35eoooooooooAPXU-4aUi^^^^^^^^^^^j----||rr^rr1vLJfCeOjhkZERQ64AAAAAAaaa4S2JoHMNQQ\n"+ +"Qgzv||1rrrr^^^^^^^r2tlpw22222ooee25XLhe2k1^^^rifaS22c ---tM4rrr^^^rrrrrqeaXUmk8RZa4aAAAAA222AAoYxYAQ\n"+ +"NRLr^^^^^^^^^^^^^Yyymp6EqHq9kkkJrtezca2e6JJXdmPZp8bOr - -tRRRr^vTr^^^^^e635hkE2BPstsuyoo22222222oxIQ\n"+ +"MRL^^^^^^^^^^^^^yyOH6G6UXZS4PXCCGkZA2ZAURRRR88888O8br -LR8R8|^|mUDAJ|UmjeSeuwRdx^^rrr|vitIzCyyeJfN\n"+ +"MRL^^^^^^^^^^^rUG8H64ooa4SPkG6kmUX5UpO8888888888bHb8r -rO88RI^^^oR8zt2kajeaXOV5X^--^^^^^rFr1|e9vfN\n"+ +"MRL^^^^^^^^^^^8888aoA2o2AAA2APGP6Uwm888HHHb88HdDHHHOz -rm8RX^^-^^vr-^--^vnCAwk2Or^^^^--^oACrSG3rfN\n"+ +"MRL^^^^^^^^^^rQHU2A22222AA5Paeo2ToR88RbbbO88RRR8888Om- --^S8R2^^^^^^^^ -|y25Upq^^^^rTaoSGG99I^YN\n"+ +"MRL^^^^^^^^-^em45w5Z55wPP2C3cFrzRR8808HdH888OHdpqqpHR^ --^x88DI^---v- -iF24kmU^voXwU69E6h4|^YN\n"+ +"MRL^^^^^^^v2EPPkPPPPX55AyF|^FrORg8wASG88888HpppppppdO5----rpHddavLv- - ^oFj5UG4ASSrCGUS239i|FN\n"+ +"MRc^^^-rxj33F5OpppHPZAoeTv|SLg8CvFmR88888pmmGmHbpqppd8v---^zbOu^r^^ --r^-vyE2X6A^GAyyykHbjsN\n"+ +"MR7^^^^------vQO9dPooyoelTApVr|ZROHOpO88Hm6q88HmOHppdHm^---r^-^|^ -ryr-^^CUAx^Pka229UEp4sN\n"+ +"NRT^^--------^Qpkq2oeeAyCev^JO8Hb8kebR8Opm88ODb8qpdqqGby-^^^vrr^----- -^---^^TmocjZy3yVV33yssN\n"+ +"NRT^---------^gGkk2oy2kF^^z99dH8DlvPR88pO8OOdOpmppmmmGpHe^T^ -^3r--^-LqzXwr74oeyyyeFsN\n"+ +"NRT^----------8kkS2Ae|--|IoGb88avvvvF8DOdOOdHdqGdmGG9mqqmI- --^^iv^tAUmu4^uahkPXXysN\n"+ +"N8T-----------GwkkF^-rCpOGGH88ObOEtvLHa5HqdqppqqpGG66G6mq| - --^-^FyGOUP52UGS455ysN\n"+ +"N8T-----------4P|^JE08ReSHdbb88O88Jl8T|vvqH5OdGqpmGG69m9Gj -^- ^- -------t66GkSSeeX96m2sN\n"+ +"NRT----------rrLmgRRR8t6bHdqOHdbbqE856Hpm82tHm4pdpqmqEGE9P- -^^-- -^v|r^- --rqowASe2eeyUq2sN\n"+ +"MRT--------^vz8R8pGkOvmpDmqbqmpHqqHqbODbbqi|IC|iEHqpqE4kEU^--^r^^^^^^^^^^^^r|||J^ --rGjozSP2yee3mAsN\n"+ +"MRT-------tomjSSaAzE|XppmmqGmmpmHm9mmqGOqqwvSLT7|ukAeGzf6E2Cj|F3|tAoSPPZoyjj3343r---r62xePkUPa2yASsN\n"+ +"NR7^-----xUr--a44CkvSbpqqq96GqmmwP99mirDmmEGX69G4i|vAUj|EUk23^1a3lz2r-- --------^---^d9a3kkkkkUXyasN\n"+ +"NRi^----^e----PSAGtk8ppqd9E9GmmPkw67^^UkOk59P9PPkkozmk3zAjaZPl^lv^rCC-^^-------------4p6eekUkkkky2sN\n"+ +"NRT---- v--- rPS6id8ddpH9UEEGm9aP7- -kEGkkkPPZ5wkEPHPwGAs22aoy|A4cLr----------------rMjooAwkPPPe3sN\n"+ +"MRi ----^----amaFROpHHO9UkkUGqAU|-- ^EsZa5w5S2ASwX5p4w5ww5ElaAAzav-----------^^^^^--tp8ejeASXPkAfsN\n"+ +"MRT---------tk3qROO8R896kEGqqmD8O88Z7j4vS2U4a2eoAaaSU2aA4A4S^LmXkmb8@g88OdO8Om2Ftt|r^^^k2CyyaEEk5JsN\n"+ +"MRT-------^v29RRRRRR8pmEPkk9mw^^COZ5XqkVAeU2oyeyoAeC2e22AAZoFrkmm9qp8RpmmmO8RdA|GObG2tjIeyyyo2aGmzzN\n"+ +"MRT-rTvvveEmOO88888GE9dUPXPpv2- zC^vPCGpAAiyeuCuyoA|43eyeyw2|-^k8mGq8OdqmH888yYJTymRR5TJeyye222kkrzN\n"+ +"NR7---^|JmpD88mpU2uy66bkwwk8--r--u^-^^r2|r^^IV3uCoa-CyeVyyc2F -^6bbqHppmmb88m^ -^rvpR82uoyeeA22mr^zN\n"+ +"NR7----ryooCPPGS4wSAGpbUwhk8^ --^^^^^r- -^vAt rAeCyeto4- -rHpGDqpGH8OOf^^^^^vwR8Oe2yeoSo2k-^zN\n"+ +"MRtmyxPZPPeYE5mGkXA2mHbGZw6Y^ ----r- ^1Jkkkuo5mpAj^jpO6Dqp8HGOx|rLvveq888q2ee2hy5L ^zN\n"+ +"MR7ZAoaqwE9PGGGkwaeGOdHpwwmx| -4|LajA59UmPCmkmmqOHGmUauAATyAPOO8R9yoAPVk^-^zN\n"+ +"NRTIIHG9XP5UmmGUkPkvpqpdPPUrv- r--^-7G^-ok5kkGGpGkkOeoAkSz|SaSGOb8qo4PCS--^zN\n"+ +"NRcIDm9UkZGDGG9EG2L7CHpp9Ua^^r -- --^r|^^^xvL5w9GqU5wGP2A4kalcoyoaZkpH8qEyo--^zN\n"+ +"NRTmmGEaGUb5e99G2jr^^DdGGUa^^r^ --- -^ ------cPk9mU445wPS4SSPoaxoyyeeo5aXmpbZ^-^zN\n"+ +"N8TGm9P2ap5eyP9PT|^^^|89EXO^^^r^ -- -^wPGUPAAAS4soa4whko2Auyeee2we25ZEL -^zN\n"+ +"MRTG9kUL^Uweuapijr^^^^SmUkqy^^^^r^ -- -^r1Lyw5FPSAAAASVc-zy2ZwhPmjAyeeoAPoA55kc -^zN\n"+ +"MRTkk9|-^^qPl2krT|^^^^^6Ek6kt|r - ^^^^-^^Z2k3|^^^^^^^^^wEkf7| zPxx6nigBx2s9XyN\n"+ +"N8Tg2^^^vqv++++++nrr+^^^r - --- -- ------YqDpc^vkk^rqaHkG4e-|r5pGLh3vvqq44--^z3o2-sN\n"; + System.out.println("Hello from\n" + logo); + } +} + From ac4ec149033394ad68889a44e77d8d3cbbba6252 Mon Sep 17 00:00:00 2001 From: Ayu Date: Sun, 2 Feb 2025 04:34:21 +0800 Subject: [PATCH 02/43] updated logo to be bigger --- src/main/java/Sparkle.java | 119 ++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 42 deletions(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index 6af1511fa..d252bc739 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -1,46 +1,81 @@ public class Sparkle { public static void main(String[] args) { - String logo = "QQQQQQQNggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggNQQQQQQQ\n"+ -"QQQQQNNHiiLL777cc7cuIsFfIIYjeziijzjjFsurrrrrrrrrrrrrrTLTirrrr111|||vi7IzIzFoS4jJxllIIfYFFFfvpNNQQQQQ\n"+ -"QQQQNM8lLTttttttttcy5AaaA22o2a5SEPkPj-mT^^^^^^^^^^^^v^--^vr^^^^rrvTFyoZGekkkBBbk4ZwXPkkEE962t8MNNQQQ\n"+ -"QQNMbAcLcLiivv||rrr^35eoooooooooAPXU-4aUi^^^^^^^^^^^j----||rr^rr1vLJfCeOjhkZERQ64AAAAAAaaa4S2JoHMNQQ\n"+ -"Qgzv||1rrrr^^^^^^^r2tlpw22222ooee25XLhe2k1^^^rifaS22c ---tM4rrr^^^rrrrrqeaXUmk8RZa4aAAAAA222AAoYxYAQ\n"+ -"NRLr^^^^^^^^^^^^^Yyymp6EqHq9kkkJrtezca2e6JJXdmPZp8bOr - -tRRRr^vTr^^^^^e635hkE2BPstsuyoo22222222oxIQ\n"+ -"MRL^^^^^^^^^^^^^yyOH6G6UXZS4PXCCGkZA2ZAURRRR88888O8br -LR8R8|^|mUDAJ|UmjeSeuwRdx^^rrr|vitIzCyyeJfN\n"+ -"MRL^^^^^^^^^^^rUG8H64ooa4SPkG6kmUX5UpO8888888888bHb8r -rO88RI^^^oR8zt2kajeaXOV5X^--^^^^^rFr1|e9vfN\n"+ -"MRL^^^^^^^^^^^8888aoA2o2AAA2APGP6Uwm888HHHb88HdDHHHOz -rm8RX^^-^^vr-^--^vnCAwk2Or^^^^--^oACrSG3rfN\n"+ -"MRL^^^^^^^^^^rQHU2A22222AA5Paeo2ToR88RbbbO88RRR8888Om- --^S8R2^^^^^^^^ -|y25Upq^^^^rTaoSGG99I^YN\n"+ -"MRL^^^^^^^^-^em45w5Z55wPP2C3cFrzRR8808HdH888OHdpqqpHR^ --^x88DI^---v- -iF24kmU^voXwU69E6h4|^YN\n"+ -"MRL^^^^^^^v2EPPkPPPPX55AyF|^FrORg8wASG88888HpppppppdO5----rpHddavLv- - ^oFj5UG4ASSrCGUS239i|FN\n"+ -"MRc^^^-rxj33F5OpppHPZAoeTv|SLg8CvFmR88888pmmGmHbpqppd8v---^zbOu^r^^ --r^-vyE2X6A^GAyyykHbjsN\n"+ -"MR7^^^^------vQO9dPooyoelTApVr|ZROHOpO88Hm6q88HmOHppdHm^---r^-^|^ -ryr-^^CUAx^Pka229UEp4sN\n"+ -"NRT^^--------^Qpkq2oeeAyCev^JO8Hb8kebR8Opm88ODb8qpdqqGby-^^^vrr^----- -^---^^TmocjZy3yVV33yssN\n"+ -"NRT^---------^gGkk2oy2kF^^z99dH8DlvPR88pO8OOdOpmppmmmGpHe^T^ -^3r--^-LqzXwr74oeyyyeFsN\n"+ -"NRT^----------8kkS2Ae|--|IoGb88avvvvF8DOdOOdHdqGdmGG9mqqmI- --^^iv^tAUmu4^uahkPXXysN\n"+ -"N8T-----------GwkkF^-rCpOGGH88ObOEtvLHa5HqdqppqqpGG66G6mq| - --^-^FyGOUP52UGS455ysN\n"+ -"N8T-----------4P|^JE08ReSHdbb88O88Jl8T|vvqH5OdGqpmGG69m9Gj -^- ^- -------t66GkSSeeX96m2sN\n"+ -"NRT----------rrLmgRRR8t6bHdqOHdbbqE856Hpm82tHm4pdpqmqEGE9P- -^^-- -^v|r^- --rqowASe2eeyUq2sN\n"+ -"MRT--------^vz8R8pGkOvmpDmqbqmpHqqHqbODbbqi|IC|iEHqpqE4kEU^--^r^^^^^^^^^^^^r|||J^ --rGjozSP2yee3mAsN\n"+ -"MRT-------tomjSSaAzE|XppmmqGmmpmHm9mmqGOqqwvSLT7|ukAeGzf6E2Cj|F3|tAoSPPZoyjj3343r---r62xePkUPa2yASsN\n"+ -"NR7^-----xUr--a44CkvSbpqqq96GqmmwP99mirDmmEGX69G4i|vAUj|EUk23^1a3lz2r-- --------^---^d9a3kkkkkUXyasN\n"+ -"NRi^----^e----PSAGtk8ppqd9E9GmmPkw67^^UkOk59P9PPkkozmk3zAjaZPl^lv^rCC-^^-------------4p6eekUkkkky2sN\n"+ -"NRT---- v--- rPS6id8ddpH9UEEGm9aP7- -kEGkkkPPZ5wkEPHPwGAs22aoy|A4cLr----------------rMjooAwkPPPe3sN\n"+ -"MRi ----^----amaFROpHHO9UkkUGqAU|-- ^EsZa5w5S2ASwX5p4w5ww5ElaAAzav-----------^^^^^--tp8ejeASXPkAfsN\n"+ -"MRT---------tk3qROO8R896kEGqqmD8O88Z7j4vS2U4a2eoAaaSU2aA4A4S^LmXkmb8@g88OdO8Om2Ftt|r^^^k2CyyaEEk5JsN\n"+ -"MRT-------^v29RRRRRR8pmEPkk9mw^^COZ5XqkVAeU2oyeyoAeC2e22AAZoFrkmm9qp8RpmmmO8RdA|GObG2tjIeyyyo2aGmzzN\n"+ -"MRT-rTvvveEmOO88888GE9dUPXPpv2- zC^vPCGpAAiyeuCuyoA|43eyeyw2|-^k8mGq8OdqmH888yYJTymRR5TJeyye222kkrzN\n"+ -"NR7---^|JmpD88mpU2uy66bkwwk8--r--u^-^^r2|r^^IV3uCoa-CyeVyyc2F -^6bbqHppmmb88m^ -^rvpR82uoyeeA22mr^zN\n"+ -"NR7----ryooCPPGS4wSAGpbUwhk8^ --^^^^^r- -^vAt rAeCyeto4- -rHpGDqpGH8OOf^^^^^vwR8Oe2yeoSo2k-^zN\n"+ -"MRtmyxPZPPeYE5mGkXA2mHbGZw6Y^ ----r- ^1Jkkkuo5mpAj^jpO6Dqp8HGOx|rLvveq888q2ee2hy5L ^zN\n"+ -"MR7ZAoaqwE9PGGGkwaeGOdHpwwmx| -4|LajA59UmPCmkmmqOHGmUauAATyAPOO8R9yoAPVk^-^zN\n"+ -"NRTIIHG9XP5UmmGUkPkvpqpdPPUrv- r--^-7G^-ok5kkGGpGkkOeoAkSz|SaSGOb8qo4PCS--^zN\n"+ -"NRcIDm9UkZGDGG9EG2L7CHpp9Ua^^r -- --^r|^^^xvL5w9GqU5wGP2A4kalcoyoaZkpH8qEyo--^zN\n"+ -"NRTmmGEaGUb5e99G2jr^^DdGGUa^^r^ --- -^ ------cPk9mU445wPS4SSPoaxoyyeeo5aXmpbZ^-^zN\n"+ -"N8TGm9P2ap5eyP9PT|^^^|89EXO^^^r^ -- -^wPGUPAAAS4soa4whko2Auyeee2we25ZEL -^zN\n"+ -"MRTG9kUL^Uweuapijr^^^^SmUkqy^^^^r^ -- -^r1Lyw5FPSAAAASVc-zy2ZwhPmjAyeeoAPoA55kc -^zN\n"+ -"MRTkk9|-^^qPl2krT|^^^^^6Ek6kt|r - ^^^^-^^Z2k3|^^^^^^^^^wEkf7| zPxx6nigBx2s9XyN\n"+ -"N8Tg2^^^vqv++++++nrr+^^^r - --- -- ------YqDpc^vkk^rqaHkG4e-|r5pGLh3vvqq44--^z3o2-sN\n"; + String logo = "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n"+ + "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n"+ + "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n"+ + "QQQQQQNMMgmJiLTTtttttttttttTJX5Aaa444AA22o2AwU4S6PPkP5Pr^SSr^^^^^^^^^^^^^^^^^^rJ^ --^vir^^^^^^rrr1|LtIuyeAOP2PUkZpBBBO954S5XPPkUE9666GGGUYtGgMMNQQQQQQ\n"+ + "QQQQNNMMR5TL7TTTttTTT7cLLivv|ia42222oo2oeooooeoSPPkPPm|-tdEer^^^^^^^^^^^^^^^^^ir---- ^r|v^^^^^rr|vLtFCe2AAHGeZPU5ARBBQqU4aS444SSSSSZ5wXPP5FcSRgMMNQQQQ\n"+ + "QQNMgRH4JiLLLLivvvv||1rrrrrr^^LE5eoooooeoooooooeo4PhPk^^ko49e^^^^^^^^^^^^^^^^rJ^-----^7Trrvr^^rrr|vvi7tIzs9be2XPkZAURBR6h22AAAAAAAAAAAaaa44ettApRgMNNQ\n"+ + "QQRAFTvvv|||rrrrrr^^^^^^^^^^rwevu95oeoeoeeeeeoooeeoaP4ioZooAkC^^^^^^^r|fASaoCAs------^yMHv^rvr^^^rrrrrr|||u8AVZXPEGGSOQqwaaAAAAAAA2AAA2AAAAAAostTI34RQ\n"+ + "NQ8J|rrrrr^^^^^^^^^^^^^^^^^eZLTeU88Hmk5SZZ5S4aAAAo2a24LF5oo2Pkr-^rtoSAyA69UU5wT---- -^2R0Q5r^||^^^^^^^^^^^rqEjAwXUGpUSRgh4A4SSSS4aAAAA22222o2222oeLLON\n"+ + "NNOJ|^^^^^^^^^^^^^^^^^^^^vZIf98O6kPk9b88mGUkkkVr^rFousttA2oePPlomOO88dGkU88HHpi- -reRRRNEr^^F5t|r^^^^^-^kHey5wSaGau8Bq3tvctJYzCyeo22o22222222o27cbN\n"+ + "NNOJ1^^^^^^^^^^^^^^^^^^^lyF6RbUUmpqG9kw5SSkkkC|3EkXS2ye4422PORRRRR888888OD88Hqv -ru88RRg9|^^rmmyXUzTvrrG82joSS3jzoRQR2i^rrrrr||viTJIzCVyeeeeeo7cbM\n"+ + "NNOJ1^^^^^^^^^^^^^^^^^reyP88mmDEa2AAAaZwPPEUXkqE5Pk99kkUU68RRR8888888OdDO8O88Ov -^xO888R@kr^^^2gR8R8Fe8OUaujyASSA6qjaPt^-^^^^^^rrrrrr|vLtlIj42LcbM\n"+ + "NNOJ1^^^^^^^^^^^^^^^^rXGH8Obmw22222Aa44ZXk6G9UUGmEZa46qO8R8888888ObO8888ObHHb8J- ^imR88R8f^^^--|mRR5vrv3PkaCje2SkHmYApPr------^^^^^^TA1rrrLUmJ|cbM\n"+ + "NNOJr^^^^^^^^^^^^^^^^XQ8bR8ko2A22oo2AAAAAA2Aw9G9E6mUPGO888bHbbHH888HHHHHHbHHHOe- ^|PR88R4r^^--^^rVv-^^^--^rYuzC24w9PnkOr^^^^-------TPSe^^jEm5|r7bM\n"+ + "NNOJr^^^^^^^^^^^^^^-|WWD8H42A2222o2AAAAAAAX66AC5myJw8R8888HHOHbbDdbObbOObHddpbP^ -rARO88x^^----^r^1v^- -^7jje45k998Gr^^^^^^^-^CZoy5ASGEm2^r7bM\n"+ + "NNOJr^^^^^^^^^^^^^^-JB0pw2AA2222222AAa4PUP2jf26srsORR8808bOObO88RRgggRR8888888O| ----rj888Oj^^^^-^^^^^- - -^tyyA5PUmpC^^^^^^vyZ2o4UmG96UGe^r7bM\n"+ + "NNOJ1^^^^^^^^^^^^^-^4RkA4ZZSSSSSZ5Zwkk5yIjCYyI^c8RRR88RR888ObbOO888OHddpppppH8Ra- ----^Lm8O8UJ^-----^|^ - -rTfoASXEmdy^^ru5SA5UGG9E9GESXx-^TOM\n"+ + "NNOJr^^^^^^^^^^-^rJwkShkkPPPPPPPkPPS2C3eF1rTrrGNRR8OR0OGPkGH88888OHDDdppqqqpppbHr ----^rS8bO8moLr^^rTr -^v22e45kGqksCw4PEPAP6969E52eUT-rTOM\n"+ + "NNOJr^^^^^^--^1f56kXkkPkPPPPPPwZ4SSA2jvr^|2^TWRRMgmoFs4m8RR88888HqmqpqppppppdHORa- ----^lHOdpqHy||x|- - -^ceLLyPPm9AAAAa2^^kG9hAee3Am3LctbM\n"+ + "NNOJr^^^^-^T4k9EUEEkGmmGqpHOq6UwaAoyJvv|vA|eMWWmIrvS8gR88888R8pmmmmmmqdODpqpppdbHL-----^rkOmdUr-rrrr- --^rr^-^e2PGaoG9py-TmX2yyyC2q8bettbM\n"+ + "NNOJr^^^^^----^^^^-^4QRbq6pqaoeeyyoVJTccEePMqs^^j8R88OO88888OpmGGGGp88OqmqDDppdHOpr ----^xPCo|-L|- ^^rLv^--rvfmGz4mkrrP4yyyVekq9EpRetbM\n"+ + "NNOJr^^^^-----------uBRD6UdU2oeeye23fxLA8Gz^-|908bHHObqq8888HqmGGHRR8Hmp88dpdpppb8u-----rr---^^|r- -^vu7r^^^^rnm25s^|96kha2Ak6kE6mb3tbM\n"+ + "NNDJ|^^^------------LQRpEGma2eeee2ACYj4ar-^C88OHbHO8PCER888OdmGHR8O8Hq88pmpDpqqqmdq|--^r-^vcvvr-------- -^-^--^--rIpPoiFUwoyy3yyy3Cy3y2ItbM\n"+ + "NMdJ1^--------------|MRGkmU22oeeoAA2Sl^-rkR8ObbHO8ktTUR8888Hqd88O88qD8dmqppqmmqmGqO9rr^^v7^- --^^^----- -^rr----^^repAzky||2233yyyyyyyyyxtbM\n"+ + "NNbJ|^--------------rRRUPmw2AeyyAU4|--vSEASmpHb8pnvvlm8888Op88OO8bpb8pmmppqmmmmGGqHH9|rYr- --io|^--^^--IO2ySa9T^Jk42oeyyyyeoltbM\n"+ + "NNbx|---------------^b8PPGa22y4ac^--^vLI46HHb885LvivivldRbH8bHO8HdbHdqmmppmGGG6GmDmpqwl^ -^^^^rrv31^^J52Gq2o9v-zU5kkPwZSZhstbM\n"+ + "NMpJ1---------------^k8ZkE24Uer- -^vAq8G6pH8R8ZzsJcivvvo6bDGHO8HqppHppmmpqGGGGGGmmmpqa^ - ^^Lr1|Sa4p8kC3oIxkSooAZk9E9jtbM\n"+ + "NMmJr----------------AOahmUJ^--r2m8RHkEqdH8888RRRRdFvvvS8oJkd6mHpqpdppmqdqG6G996GUGGmkr --- - -^---rxCAmHO69kayokHpXS54aSFtbM\n"+ + "NMqJr----------------jpqar-^tU80R88Aj9OpDOOO88888Rqt|7qHx|vvvsH8EEbHpGmqpqmGGG9G9GmU6E| ---- -- ---- ----^fSGmD9PkPZeCySmGP9mmutbM\n"+ + "NMpJr----------------jC^^lm00R88RpIVbbDHHdDOOHHbb88AoR9ttCAyY9RmFa8Od6mpppqmGGmmEmGk9GJ- -^^-- ^vr^--- -------^AqPEPP5eAa2eeyAmpGmutbM\n"+ + "NNHJr--------------r|^|U@0RRRRRNGc28HbHpqpObppHbbOEE8H9q888qpOOavIGp6eSqDpqqmmq6EmU9Eme^ ^^^^^--- -rttTvr^- ---^ap24ae4woyeeeeyykDputbM\n"+ + "NNOxr------------^|rtpR88888dqRPvA8dHDmmqODmmqdHpGq8pmbOObdH8bGI||vSz||smbpqppqk9P56E6Sr -^^^^^^^^^^^^----^^^^^^rrrvxI^- ---^A6j2ozyPPAyeeeeyy9OCtbM\n"+ + "NNOJr-----------|tFpWR8qEwA3sPP|zHpppmGpbqmmqpDqmHbmmqpDpp8RHmGu||yS||v|c4ddpHmP6ee5UEPt^r7xFYlvr|r^^^^^rrr|LYeaPE69aIvvT- ---^SkjyFsAwkU52eyeeuAbytbM\n"+ + "NNOJr---------^jA9pzrJ54aaozSP1lHpqpmGqqGGGGmpqmHq9U9mmGdmhppmpGntwjitIT||f42llkUnJt9EUPozovrl3CT^lGDqHOOpG5u7v|r|v|vsPa|-----^5Eoyt3wkkkUUk5ao3eqytbM\n"+ + "NNbJr---------FpEv---jk4Sa3AUvTdbppmmpq6G6Gmqqmq95wUGk6qx^2O9pq6UmP5mGGGa7||vvzdwVT|XGUmkyev-^e2elCje2r^--- ------^^-----^odUkfCPPkkkkkkUU4e6ytbM\n"+ + "NMptr^-------vqt----^Ak44eaGvJ88ppqmbp69E9GmqmqkSk6UGqPTrtmPmGEUUG596kkk9ksvvLaH4yv|A62CV2yeFLs2Jr^rYoz^ ---^^-----------------i8mO9FekUkkkkkkUPek3tbM\n"+ + "NMptr^-------h| ----^5XSAaELC88DppqHH6EEE9GmmqkPkZXGC^--^5mm8GUhUUw9kPPPPk9PAyUp5oj4asyX99E4v^^jIrrrtje|^^^^-------------------^GRGwaeyPkUkkkkkk25jtbM\n"+ + "NMpJr-------rJ------ikSA9UvaR8dpDpDbGEUUU9GGmqka56z^-- ^SSpOUGUGPPkPwZwwPU99Pm9PSUq4lCSXaoooCvjASS3Cui^^-----------------------tgPsooSo4EkPPPPP2astbM\n"+ + "NNHJr ------rr---- -oEw8e|UROHHdqHOGUUUUU96mmZ5wt^- rkaaPh4ZUXP5waa4ZPPkXPpwPwkEU5oCeAkPCXf^Jo2r--- ----------------------|H8SyzC5aeXkPPkkA2ItbM\n"+ + "NNbT^ -------^-----|kqGcjR0bppDH8OG9UkkkUU9Dm4AUCr^-----vUofa5ASka5a422A455w4PmAZXSZ555X9U7e4CPUeePe^^-------------^^^rr^^^^---^5HH8ajuCo5aaPkkk4yJtbM\n"+ + "NNbJr-------------^kHuFp0Rbpb8R88m69PU6GqmmHqGmpH8Oqkev^IPsTS425UASAA2y2Aaa4ePGoaZAaS4a4Sk1^4G4a5UqO888ROmmqG99mmpmGwyIv||v|r^^--^i6XuCyyya99PPkwCttbM\n"+ + "NNOxr------------^eosGRRR88RRR88H6GUkkkE9mpm6PAoSbOObEGHpwvLk2ePkAAoooye22A2eZZ3AA2a4aa4ASv-^9pqG6GpDdOg8qqmmqmb888ROXSH86wVLrrr^roZ33yyyee2S6q9kATtOM\n"+ + "NNbJr----------^ifyG8RRRRR88R888GGqkPPPPkGG6j^--vOma2aaA6mGUay2w4ooy3eyye2AoyFyCoAo2222SA2AztoDGH69mpd8ROppmmmmb8888mUc^e8dbRROPCCt7yeyeyeo22eSmpGltOM\n"+ + "NNOJr-rr^^^rrijakp88888888888bmqEqmkPPwPU9lse^ vpsrrCS|zqpOXjAYJ2oCCCCCye22C|j3e2yeeee5Aat--^COOpU6mqO8DpdmGmDOR88qa2AuIy5q8R8Hzi7lyeeyeeo22o4k6jvtOM\n"+ + "NNOxr--rJeX6mqH8ObOOO88888qPoja96bmPwXwPGX^^vi- ^ji^-^eAitZmPFCTrAAnjjuu3eeaI^teVoCyyyyooAz----n8O8pqmH8pppmmpb8888Vr^-^r|Js9WRRpCJuoeeeeo2222ADA-^tOM\n"+ + "NNOJr-----^^^zmGGmH88GkdPyzjeA66mbmPwXwkmU^ -^^--|F^-----^zL^r^--^vYeeyuny24|-|ay2VyyyeLL2o^ -^^SpqOHqdHqdpGmD8R88Ov- -^rr|TDW88Ujy2yyeeoAA2e5q| ^tOM\n"+ + "NNbtr------^l2yoyC4Gk6mAyaw5aa9GpHmPwhhkqp^ - --^^r^r^-rT^ - -^rLC4G2^ ^2nCCjyeAvr35|- --^kHpmmbppHmGpO88H85r^^^^r^^|l6g8ROAe2yeee24aeyGa^ rtOM\n"+ + "NNOlt|^-^|A4eA423jZ6h9kS6kSaA4GmDbpk55Pkm2r ----- ----^-- --r^--^oX4w4A24GGZ5Sv^-^^vRpdqmGDpmpH88qp8yr^^^v^^r|ud8888pS2eeeo2SaVypJ- rtOM\n"+ + "NNOxCGqEPaS969Z2njw9Pqp9UkwaeAqpHbH95Zw99Lr - - -L^ -rv|cXUZkhlzPPmpqqOP|^ebpH9mpmppO8mqpbui|r|fxLF4mq88888qAeeeoAh4uAk^ rtOM\n"+ + "NNOJjPSAoyPmXkGmGk99mm99kS2eem8pHHbmw55G9||- ^E2TxAlF4SS9qmGmwufGd9GqmqmO8GG9HEZ2L2qFvt44PGH8O888EeeooaP4u4A^ rtOM\n"+ + "NNOJF4SaSGm6XhPX45Gq66U55XSa6PqHpHHqPww9HPo^ ^Ir-^Je1|eP6x|oEEGUUEkmGmGp8E9EqqyC2PA5SavT5uoG8OOO8RGee24PSCZJ---rtOM\n"+ + "NMHJT|vP8Gk9PXP5XmqmmGGUkkEE7|68mpppUwkG|^rr ^^-----^uGi--^Ska2PhEGG6pHPPk68wVo2A5Gus1LeAXA4GDHO8RHAoZPSyw|---rtOM\n"+ + "NMDJ|LqHmGPEUhZkqpHqG99EEGAvTsCdqdpp6k9kr^^i^ -- --^^^^vvr--^teIvzkSP66Gpq55wkG6A22A4wquliteyye4wwXEqpO8Hkw42hr --rtOM\n"+ + "NNHJybqmm65k65Ppbpaa9E9EmoLVv^^PRqqmm9Ukr^^r|- ------ -^- --^^^^rt|^-^jwSU99mqk4ZZPU6P2aaaSwmYjJtyyyeeee2hGGqb88RbkXr---rtOM\n"+ + "NNbJ3qqm6E5aGwmO9ey5U99p2Lyr^^^v8OG6G6kkr^^^rr- - -- -^- - ----- -r45P99GmkAa44X55wS4S5SShEYaAlyyyyeeee2Zoe25E6m8qJr^-rtOM\n"+ + "NMpJCmmG9kXeXGq92yy4kkqkt2|^^^^^j8mE9U5bT^^^^r|- - ---- ^jwhEGGE5AAAAAha2Z24S45XwkZy2ya3yyyeeooAw2eoa55wGy- --rtOM\n"+ + "NMHJCmG9UPGyrkpaAyu259qLty^^^^^^^U8EEUwbGr^^^^rr^- --- --^rf59GGEka22AAAAwo3r|ooAa5XPEAwEt4eyyeeeeoAXAe245Zwp2- --rtOM\n"+ + "NNOxCG9kP9o^-1mG2ynyap4rTj^^^^^^^LbGkEP9qu^^^^^^^|^ -- -^|itzo5UUPeie5a4AAaAAaPufr-^3CeAS5wwam8eu4Cyeeee2aPSe2S5w5Go- --rtOM\n"+ + "NNOxuUkPmC^-^-|8q2YjaGF^vVr^^^^^^^zdEUX9kkt^^^^^^^r|- ------ --^|Iv^- ^PZZaAaAa5P3Ir -IyC2aZw4UG9EySCyeeeoA4Pwo2S5556S^ --rtOM\n"+ + "NNOJjXk9t^-^^--rGGaz2klrrAv^^^^^^^^2qEP6mP6f^^^^^^|ke^- ^r1^^^rr1ySS4AAASPUAzr- veu2A4SUpkZG45ACyeeoa4XPA2S555k9| rtOM\n"+ + "NNbJj9P|^-^^-- rmSaUUjrrJor^^^^^^^^SqUGkvv2Av^^^^YP|^r- -^|2i^^^^^^-chAa4A2wkU5ot^^-- |2C2A4kSy4UUZkhnyyeeaShk4ASwwwwG2- ^tOM\n"+ + "NNbJVe^^^^^- --- ^Xko5Syv^xyrr^^^^^^^up9qF^rr^^^^|aer^^r^- ---^|IJrvUF^^^^^^^vS4AaawE999w1- ---^Joy2Ame-^r3m4kPjC3yea5Xkw4S5w5h9mv- ^tOM\n"+ + "NNblv^^^^^--^--^^-^ekaS46Us4errr^^^^^^vkkkPCv||^^7hl^^^^^rr^----^^^r|v7xsCoaAIr^iGu^^^^^^^|aSAaPU9UEqe^ -C2e2U3- -L^jEmPzyeo2SwwUPSSw5w9S3kr ^tOM\n"+ + "NNOJvr^^^-rr-^^^----r5GkAwkUm4vrrr^^^^^ryPPj^^^ -i4i^^^^^^^rtYJs2SA2eyy3jt1^^-^fEy^^^^^^^v4SAZPkUUmmL- ^5o2Ua^ ^vtGqmwZSaSZ44ZXkPkkUO9rfa-^tOM\n"+ + "NNbtv^^^ r1^^^rr^----^yEPU9UX4PV|rr^^^^^-|zAki- -vAJ^^^^rr|JfT7i^^r^^^^^^^^^^^jUJ^^^^^^^Jk5ZhPhP9qC^ TE4kv-rr-^vAauYffFsssssuAASk6UE99E6RAitOM\n"+ + "NNOJv^^ -rr^^^^rCyvrr^^F6PXPkk2aAL|r^^^- ---rJv^-r2i^rrtIvr^^^rv^^^^^^^^^^^^rV2v^^^--^ckk5PkkPUmA^ ^EqP^ -fPsTxfFsszzzzjzjF7tlF2U6k6mqmbstOM\n"+ + "NNbJLr^rv|rrr^^uPS52Yv^-1PaA2eo2yzF|^- ----r2Trt7v^--- -^vv^^^^^^^^^|t2zr- --rCGU5kUUPkGPr- -eU|- -|oCsJIYYFssjzzjzjjYtlye22eSdOdpDstOM\n"+ + "NNbxi|vtu|rrrrv5hPkkytv|vV4e3eAejfeT- ^3jT||ir^-----^ir^^^^^--^I23oyuy4GGw5kEkPP5jr- --- -rv^ ^waFAAy442VujnnjsjyeyJv||LlYT|iyUbztOM\n"+ + "NQOJT|^|lrrrrrFEPUUolxteAya2sItloejv- -LeTr1vr^^^^^^|t^- -vSY^ -rLAUS4h542Ccr^-- ---- -- ^94CoZAye22AaAA2oAIrrriCFyXZkEAtJvr|tON\n"+ + "QQ8YtJLtTr^rrreGkEkjJtJ4S3Aw3TLvilyc- ^as|r|rrvrr1|Jl^ ^Ca|- -^Lyoe2ezcr^^^^- ------ ^Hk2ya5Z5S4w4oeey2Sr^JezTAaw9hSc^vzl7l8N\n"+ + "QQN08dZstL|rrr2Gk6kzt7sS2CA4Af|1||TL- -Torrvietrvir^- -vAIrrLzAaeCJ|r^^^^^^- ------ -ADSAVA2y2k5eCCCzFze|^TCESvr1rvlTT3PH80MQ\n"+ + "QQQQNNMRmVtTLvAmU6UjtcjAyuAAASu|rrv|- ^2z^^^^^^-- -rAI^ ------^--^^^-- ------ rDaSSS4ZU5yCy3jFFzsyirTCoXPoT||t2OgMNNQQQ\n"+ + "QQQQQQQNNRSxTvVdEGECJcsSojV4a5t^rrLr -LUr -r2u^- -----^^^^---- - ------ -om4S5SU62yooenszssf3t^|oneuTi7lUgMNNQQQQQ\n"+ + "QQQQQQQQNMgGlLT9qUG2x7JSS2zICSA^-Jx- ^eo^ -^yer- ------- - -- ---- ^Gk5kk9SFsnzuCCCe2225y^^jzPi^|J9gNNQQQQQQQ\n"+ + "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n"+ + "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; + System.out.println("Hello from\n" + logo); } -} - +} \ No newline at end of file From 7718ae1cd58a5ae83d1120ce670c84c3c7fdaa22 Mon Sep 17 00:00:00 2001 From: Ayu Date: Sun, 2 Feb 2025 04:42:02 +0800 Subject: [PATCH 03/43] changed greeting message --- src/main/java/Sparkle.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index d252bc739..b23374f48 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -76,6 +76,14 @@ public static void main(String[] args) { "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n"+ "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; - System.out.println("Hello from\n" + logo); + System.out.println("Hey hey, I'm Sparkle!\n" + logo); + System.out.println("_____________________________"+ + "_______________________________\n" + + " Got any cool, daring quests or risky biz? Just hit me up!\n" + + "_________________________________"+ + "___________________________\n" + + " See you around, Stelle~ Try to stay out of trouble, especially... the next time we meet!\n" + + "_________________________________"+ + "___________________________\n"); } } \ No newline at end of file From a79ea257fff3b7284a25362a82e99f191ed994cc Mon Sep 17 00:00:00 2001 From: Ayu Date: Sun, 2 Feb 2025 04:53:34 +0800 Subject: [PATCH 04/43] added echo behavior to Sparkle --- src/main/java/Sparkle.java | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index b23374f48..1e608101a 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -1,5 +1,9 @@ +import java.util.Scanner; + public class Sparkle { public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + String logo = "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n"+ "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n"+ "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n"+ @@ -76,14 +80,33 @@ public static void main(String[] args) { "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n"+ "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; - System.out.println("Hey hey, I'm Sparkle!\n" + logo); - System.out.println("_____________________________"+ + System.out.println(" _____________________________"+ + "_______________________________\n" + " Hey hey, I'm Sparkle!\n" + " _____________________________"+ + "_______________________________\n" + "\n" + logo); + + System.out.println(" _____________________________"+ "_______________________________\n" + - " Got any cool, daring quests or risky biz? Just hit me up!\n" + - "_________________________________"+ + " Got any cool, daring quests or risky biz? Just hit me up!\n"+ + " _____________________________"+ + "_______________________________\n"); + + String userInput = scanner.nextLine(); + while(!userInput.equalsIgnoreCase("bye")){ + System.out.println(" _________________________________"+ + "___________________________\n"+ + " "+ + userInput+ "~" + + "\n"+ + " _________________________________"+ + "___________________________\n"); + userInput = scanner.nextLine(); + } + + System.out.println(" _________________________________"+ "___________________________\n" + - " See you around, Stelle~ Try to stay out of trouble, especially... the next time we meet!\n" + - "_________________________________"+ + " See you around, Stelle~ Try to stay out of trouble, especially... the next time we meet!\n" + + " _________________________________"+ "___________________________\n"); + scanner.close(); } } \ No newline at end of file From b9f6cadb3321b4af3d6a602411656e29d48c258f Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 03:56:34 +0800 Subject: [PATCH 05/43] Add Task class and marking method --- src/main/java/Task.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..0e1d775a0 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,17 @@ +public class Task { + protected String description; + protected boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public String getStatusIcon() { + return (isDone ? "X" : " "); // mark done task with X + } + + public void markAsDone() { + this.isDone = true; + } +} \ No newline at end of file From fc8da49a00110ebf80b39cbe2a0cb68014558a85 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 03:57:36 +0800 Subject: [PATCH 06/43] Add markAsUndone method to enable unchecking --- src/main/java/Sparkle.java | 362 ++++++++++++++++++++++++++----------- src/main/java/Task.java | 6 + 2 files changed, 264 insertions(+), 104 deletions(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index 1e608101a..5ecbfc48f 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -1,112 +1,266 @@ import java.util.Scanner; public class Sparkle { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); - String logo = "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n"+ - "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n"+ - "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n"+ - "QQQQQQNMMgmJiLTTtttttttttttTJX5Aaa444AA22o2AwU4S6PPkP5Pr^SSr^^^^^^^^^^^^^^^^^^rJ^ --^vir^^^^^^rrr1|LtIuyeAOP2PUkZpBBBO954S5XPPkUE9666GGGUYtGgMMNQQQQQQ\n"+ - "QQQQNNMMR5TL7TTTttTTT7cLLivv|ia42222oo2oeooooeoSPPkPPm|-tdEer^^^^^^^^^^^^^^^^^ir---- ^r|v^^^^^rr|vLtFCe2AAHGeZPU5ARBBQqU4aS444SSSSSZ5wXPP5FcSRgMMNQQQQ\n"+ - "QQNMgRH4JiLLLLivvvv||1rrrrrr^^LE5eoooooeoooooooeo4PhPk^^ko49e^^^^^^^^^^^^^^^^rJ^-----^7Trrvr^^rrr|vvi7tIzs9be2XPkZAURBR6h22AAAAAAAAAAAaaa44ettApRgMNNQ\n"+ - "QQRAFTvvv|||rrrrrr^^^^^^^^^^rwevu95oeoeoeeeeeoooeeoaP4ioZooAkC^^^^^^^r|fASaoCAs------^yMHv^rvr^^^rrrrrr|||u8AVZXPEGGSOQqwaaAAAAAAA2AAA2AAAAAAostTI34RQ\n"+ - "NQ8J|rrrrr^^^^^^^^^^^^^^^^^eZLTeU88Hmk5SZZ5S4aAAAo2a24LF5oo2Pkr-^rtoSAyA69UU5wT---- -^2R0Q5r^||^^^^^^^^^^^rqEjAwXUGpUSRgh4A4SSSS4aAAAA22222o2222oeLLON\n"+ - "NNOJ|^^^^^^^^^^^^^^^^^^^^vZIf98O6kPk9b88mGUkkkVr^rFousttA2oePPlomOO88dGkU88HHpi- -reRRRNEr^^F5t|r^^^^^-^kHey5wSaGau8Bq3tvctJYzCyeo22o22222222o27cbN\n"+ - "NNOJ1^^^^^^^^^^^^^^^^^^^lyF6RbUUmpqG9kw5SSkkkC|3EkXS2ye4422PORRRRR888888OD88Hqv -ru88RRg9|^^rmmyXUzTvrrG82joSS3jzoRQR2i^rrrrr||viTJIzCVyeeeeeo7cbM\n"+ - "NNOJ1^^^^^^^^^^^^^^^^^reyP88mmDEa2AAAaZwPPEUXkqE5Pk99kkUU68RRR8888888OdDO8O88Ov -^xO888R@kr^^^2gR8R8Fe8OUaujyASSA6qjaPt^-^^^^^^rrrrrr|vLtlIj42LcbM\n"+ - "NNOJ1^^^^^^^^^^^^^^^^rXGH8Obmw22222Aa44ZXk6G9UUGmEZa46qO8R8888888ObO8888ObHHb8J- ^imR88R8f^^^--|mRR5vrv3PkaCje2SkHmYApPr------^^^^^^TA1rrrLUmJ|cbM\n"+ - "NNOJr^^^^^^^^^^^^^^^^XQ8bR8ko2A22oo2AAAAAA2Aw9G9E6mUPGO888bHbbHH888HHHHHHbHHHOe- ^|PR88R4r^^--^^rVv-^^^--^rYuzC24w9PnkOr^^^^-------TPSe^^jEm5|r7bM\n"+ - "NNOJr^^^^^^^^^^^^^^-|WWD8H42A2222o2AAAAAAAX66AC5myJw8R8888HHOHbbDdbObbOObHddpbP^ -rARO88x^^----^r^1v^- -^7jje45k998Gr^^^^^^^-^CZoy5ASGEm2^r7bM\n"+ - "NNOJr^^^^^^^^^^^^^^-JB0pw2AA2222222AAa4PUP2jf26srsORR8808bOObO88RRgggRR8888888O| ----rj888Oj^^^^-^^^^^- - -^tyyA5PUmpC^^^^^^vyZ2o4UmG96UGe^r7bM\n"+ - "NNOJ1^^^^^^^^^^^^^-^4RkA4ZZSSSSSZ5Zwkk5yIjCYyI^c8RRR88RR888ObbOO888OHddpppppH8Ra- ----^Lm8O8UJ^-----^|^ - -rTfoASXEmdy^^ru5SA5UGG9E9GESXx-^TOM\n"+ - "NNOJr^^^^^^^^^^-^rJwkShkkPPPPPPPkPPS2C3eF1rTrrGNRR8OR0OGPkGH88888OHDDdppqqqpppbHr ----^rS8bO8moLr^^rTr -^v22e45kGqksCw4PEPAP6969E52eUT-rTOM\n"+ - "NNOJr^^^^^^--^1f56kXkkPkPPPPPPwZ4SSA2jvr^|2^TWRRMgmoFs4m8RR88888HqmqpqppppppdHORa- ----^lHOdpqHy||x|- - -^ceLLyPPm9AAAAa2^^kG9hAee3Am3LctbM\n"+ - "NNOJr^^^^-^T4k9EUEEkGmmGqpHOq6UwaAoyJvv|vA|eMWWmIrvS8gR88888R8pmmmmmmqdODpqpppdbHL-----^rkOmdUr-rrrr- --^rr^-^e2PGaoG9py-TmX2yyyC2q8bettbM\n"+ - "NNOJr^^^^^----^^^^-^4QRbq6pqaoeeyyoVJTccEePMqs^^j8R88OO88888OpmGGGGp88OqmqDDppdHOpr ----^xPCo|-L|- ^^rLv^--rvfmGz4mkrrP4yyyVekq9EpRetbM\n"+ - "NNOJr^^^^-----------uBRD6UdU2oeeye23fxLA8Gz^-|908bHHObqq8888HqmGGHRR8Hmp88dpdpppb8u-----rr---^^|r- -^vu7r^^^^rnm25s^|96kha2Ak6kE6mb3tbM\n"+ - "NNDJ|^^^------------LQRpEGma2eeee2ACYj4ar-^C88OHbHO8PCER888OdmGHR8O8Hq88pmpDpqqqmdq|--^r-^vcvvr-------- -^-^--^--rIpPoiFUwoyy3yyy3Cy3y2ItbM\n"+ - "NMdJ1^--------------|MRGkmU22oeeoAA2Sl^-rkR8ObbHO8ktTUR8888Hqd88O88qD8dmqppqmmqmGqO9rr^^v7^- --^^^----- -^rr----^^repAzky||2233yyyyyyyyyxtbM\n"+ - "NNbJ|^--------------rRRUPmw2AeyyAU4|--vSEASmpHb8pnvvlm8888Op88OO8bpb8pmmppqmmmmGGqHH9|rYr- --io|^--^^--IO2ySa9T^Jk42oeyyyyeoltbM\n"+ - "NNbx|---------------^b8PPGa22y4ac^--^vLI46HHb885LvivivldRbH8bHO8HdbHdqmmppmGGG6GmDmpqwl^ -^^^^rrv31^^J52Gq2o9v-zU5kkPwZSZhstbM\n"+ - "NMpJ1---------------^k8ZkE24Uer- -^vAq8G6pH8R8ZzsJcivvvo6bDGHO8HqppHppmmpqGGGGGGmmmpqa^ - ^^Lr1|Sa4p8kC3oIxkSooAZk9E9jtbM\n"+ - "NMmJr----------------AOahmUJ^--r2m8RHkEqdH8888RRRRdFvvvS8oJkd6mHpqpdppmqdqG6G996GUGGmkr --- - -^---rxCAmHO69kayokHpXS54aSFtbM\n"+ - "NMqJr----------------jpqar-^tU80R88Aj9OpDOOO88888Rqt|7qHx|vvvsH8EEbHpGmqpqmGGG9G9GmU6E| ---- -- ---- ----^fSGmD9PkPZeCySmGP9mmutbM\n"+ - "NMpJr----------------jC^^lm00R88RpIVbbDHHdDOOHHbb88AoR9ttCAyY9RmFa8Od6mpppqmGGmmEmGk9GJ- -^^-- ^vr^--- -------^AqPEPP5eAa2eeyAmpGmutbM\n"+ - "NNHJr--------------r|^|U@0RRRRRNGc28HbHpqpObppHbbOEE8H9q888qpOOavIGp6eSqDpqqmmq6EmU9Eme^ ^^^^^--- -rttTvr^- ---^ap24ae4woyeeeeyykDputbM\n"+ - "NNOxr------------^|rtpR88888dqRPvA8dHDmmqODmmqdHpGq8pmbOObdH8bGI||vSz||smbpqppqk9P56E6Sr -^^^^^^^^^^^^----^^^^^^rrrvxI^- ---^A6j2ozyPPAyeeeeyy9OCtbM\n"+ - "NNOJr-----------|tFpWR8qEwA3sPP|zHpppmGpbqmmqpDqmHbmmqpDpp8RHmGu||yS||v|c4ddpHmP6ee5UEPt^r7xFYlvr|r^^^^^rrr|LYeaPE69aIvvT- ---^SkjyFsAwkU52eyeeuAbytbM\n"+ - "NNOJr---------^jA9pzrJ54aaozSP1lHpqpmGqqGGGGmpqmHq9U9mmGdmhppmpGntwjitIT||f42llkUnJt9EUPozovrl3CT^lGDqHOOpG5u7v|r|v|vsPa|-----^5Eoyt3wkkkUUk5ao3eqytbM\n"+ - "NNbJr---------FpEv---jk4Sa3AUvTdbppmmpq6G6Gmqqmq95wUGk6qx^2O9pq6UmP5mGGGa7||vvzdwVT|XGUmkyev-^e2elCje2r^--- ------^^-----^odUkfCPPkkkkkkUU4e6ytbM\n"+ - "NMptr^-------vqt----^Ak44eaGvJ88ppqmbp69E9GmqmqkSk6UGqPTrtmPmGEUUG596kkk9ksvvLaH4yv|A62CV2yeFLs2Jr^rYoz^ ---^^-----------------i8mO9FekUkkkkkkUPek3tbM\n"+ - "NMptr^-------h| ----^5XSAaELC88DppqHH6EEE9GmmqkPkZXGC^--^5mm8GUhUUw9kPPPPk9PAyUp5oj4asyX99E4v^^jIrrrtje|^^^^-------------------^GRGwaeyPkUkkkkkk25jtbM\n"+ - "NMpJr-------rJ------ikSA9UvaR8dpDpDbGEUUU9GGmqka56z^-- ^SSpOUGUGPPkPwZwwPU99Pm9PSUq4lCSXaoooCvjASS3Cui^^-----------------------tgPsooSo4EkPPPPP2astbM\n"+ - "NNHJr ------rr---- -oEw8e|UROHHdqHOGUUUUU96mmZ5wt^- rkaaPh4ZUXP5waa4ZPPkXPpwPwkEU5oCeAkPCXf^Jo2r--- ----------------------|H8SyzC5aeXkPPkkA2ItbM\n"+ - "NNbT^ -------^-----|kqGcjR0bppDH8OG9UkkkUU9Dm4AUCr^-----vUofa5ASka5a422A455w4PmAZXSZ555X9U7e4CPUeePe^^-------------^^^rr^^^^---^5HH8ajuCo5aaPkkk4yJtbM\n"+ - "NNbJr-------------^kHuFp0Rbpb8R88m69PU6GqmmHqGmpH8Oqkev^IPsTS425UASAA2y2Aaa4ePGoaZAaS4a4Sk1^4G4a5UqO888ROmmqG99mmpmGwyIv||v|r^^--^i6XuCyyya99PPkwCttbM\n"+ - "NNOxr------------^eosGRRR88RRR88H6GUkkkE9mpm6PAoSbOObEGHpwvLk2ePkAAoooye22A2eZZ3AA2a4aa4ASv-^9pqG6GpDdOg8qqmmqmb888ROXSH86wVLrrr^roZ33yyyee2S6q9kATtOM\n"+ - "NNbJr----------^ifyG8RRRRR88R888GGqkPPPPkGG6j^--vOma2aaA6mGUay2w4ooy3eyye2AoyFyCoAo2222SA2AztoDGH69mpd8ROppmmmmb8888mUc^e8dbRROPCCt7yeyeyeo22eSmpGltOM\n"+ - "NNOJr-rr^^^rrijakp88888888888bmqEqmkPPwPU9lse^ vpsrrCS|zqpOXjAYJ2oCCCCCye22C|j3e2yeeee5Aat--^COOpU6mqO8DpdmGmDOR88qa2AuIy5q8R8Hzi7lyeeyeeo22o4k6jvtOM\n"+ - "NNOxr--rJeX6mqH8ObOOO88888qPoja96bmPwXwPGX^^vi- ^ji^-^eAitZmPFCTrAAnjjuu3eeaI^teVoCyyyyooAz----n8O8pqmH8pppmmpb8888Vr^-^r|Js9WRRpCJuoeeeeo2222ADA-^tOM\n"+ - "NNOJr-----^^^zmGGmH88GkdPyzjeA66mbmPwXwkmU^ -^^--|F^-----^zL^r^--^vYeeyuny24|-|ay2VyyyeLL2o^ -^^SpqOHqdHqdpGmD8R88Ov- -^rr|TDW88Ujy2yyeeoAA2e5q| ^tOM\n"+ - "NNbtr------^l2yoyC4Gk6mAyaw5aa9GpHmPwhhkqp^ - --^^r^r^-rT^ - -^rLC4G2^ ^2nCCjyeAvr35|- --^kHpmmbppHmGpO88H85r^^^^r^^|l6g8ROAe2yeee24aeyGa^ rtOM\n"+ - "NNOlt|^-^|A4eA423jZ6h9kS6kSaA4GmDbpk55Pkm2r ----- ----^-- --r^--^oX4w4A24GGZ5Sv^-^^vRpdqmGDpmpH88qp8yr^^^v^^r|ud8888pS2eeeo2SaVypJ- rtOM\n"+ - "NNOxCGqEPaS969Z2njw9Pqp9UkwaeAqpHbH95Zw99Lr - - -L^ -rv|cXUZkhlzPPmpqqOP|^ebpH9mpmppO8mqpbui|r|fxLF4mq88888qAeeeoAh4uAk^ rtOM\n"+ - "NNOJjPSAoyPmXkGmGk99mm99kS2eem8pHHbmw55G9||- ^E2TxAlF4SS9qmGmwufGd9GqmqmO8GG9HEZ2L2qFvt44PGH8O888EeeooaP4u4A^ rtOM\n"+ - "NNOJF4SaSGm6XhPX45Gq66U55XSa6PqHpHHqPww9HPo^ ^Ir-^Je1|eP6x|oEEGUUEkmGmGp8E9EqqyC2PA5SavT5uoG8OOO8RGee24PSCZJ---rtOM\n"+ - "NMHJT|vP8Gk9PXP5XmqmmGGUkkEE7|68mpppUwkG|^rr ^^-----^uGi--^Ska2PhEGG6pHPPk68wVo2A5Gus1LeAXA4GDHO8RHAoZPSyw|---rtOM\n"+ - "NMDJ|LqHmGPEUhZkqpHqG99EEGAvTsCdqdpp6k9kr^^i^ -- --^^^^vvr--^teIvzkSP66Gpq55wkG6A22A4wquliteyye4wwXEqpO8Hkw42hr --rtOM\n"+ - "NNHJybqmm65k65Ppbpaa9E9EmoLVv^^PRqqmm9Ukr^^r|- ------ -^- --^^^^rt|^-^jwSU99mqk4ZZPU6P2aaaSwmYjJtyyyeeee2hGGqb88RbkXr---rtOM\n"+ - "NNbJ3qqm6E5aGwmO9ey5U99p2Lyr^^^v8OG6G6kkr^^^rr- - -- -^- - ----- -r45P99GmkAa44X55wS4S5SShEYaAlyyyyeeee2Zoe25E6m8qJr^-rtOM\n"+ - "NMpJCmmG9kXeXGq92yy4kkqkt2|^^^^^j8mE9U5bT^^^^r|- - ---- ^jwhEGGE5AAAAAha2Z24S45XwkZy2ya3yyyeeooAw2eoa55wGy- --rtOM\n"+ - "NMHJCmG9UPGyrkpaAyu259qLty^^^^^^^U8EEUwbGr^^^^rr^- --- --^rf59GGEka22AAAAwo3r|ooAa5XPEAwEt4eyyeeeeoAXAe245Zwp2- --rtOM\n"+ - "NNOxCG9kP9o^-1mG2ynyap4rTj^^^^^^^LbGkEP9qu^^^^^^^|^ -- -^|itzo5UUPeie5a4AAaAAaPufr-^3CeAS5wwam8eu4Cyeeee2aPSe2S5w5Go- --rtOM\n"+ - "NNOxuUkPmC^-^-|8q2YjaGF^vVr^^^^^^^zdEUX9kkt^^^^^^^r|- ------ --^|Iv^- ^PZZaAaAa5P3Ir -IyC2aZw4UG9EySCyeeeoA4Pwo2S5556S^ --rtOM\n"+ - "NNOJjXk9t^-^^--rGGaz2klrrAv^^^^^^^^2qEP6mP6f^^^^^^|ke^- ^r1^^^rr1ySS4AAASPUAzr- veu2A4SUpkZG45ACyeeoa4XPA2S555k9| rtOM\n"+ - "NNbJj9P|^-^^-- rmSaUUjrrJor^^^^^^^^SqUGkvv2Av^^^^YP|^r- -^|2i^^^^^^-chAa4A2wkU5ot^^-- |2C2A4kSy4UUZkhnyyeeaShk4ASwwwwG2- ^tOM\n"+ - "NNbJVe^^^^^- --- ^Xko5Syv^xyrr^^^^^^^up9qF^rr^^^^|aer^^r^- ---^|IJrvUF^^^^^^^vS4AaawE999w1- ---^Joy2Ame-^r3m4kPjC3yea5Xkw4S5w5h9mv- ^tOM\n"+ - "NNblv^^^^^--^--^^-^ekaS46Us4errr^^^^^^vkkkPCv||^^7hl^^^^^rr^----^^^r|v7xsCoaAIr^iGu^^^^^^^|aSAaPU9UEqe^ -C2e2U3- -L^jEmPzyeo2SwwUPSSw5w9S3kr ^tOM\n"+ - "NNOJvr^^^-rr-^^^----r5GkAwkUm4vrrr^^^^^ryPPj^^^ -i4i^^^^^^^rtYJs2SA2eyy3jt1^^-^fEy^^^^^^^v4SAZPkUUmmL- ^5o2Ua^ ^vtGqmwZSaSZ44ZXkPkkUO9rfa-^tOM\n"+ - "NNbtv^^^ r1^^^rr^----^yEPU9UX4PV|rr^^^^^-|zAki- -vAJ^^^^rr|JfT7i^^r^^^^^^^^^^^jUJ^^^^^^^Jk5ZhPhP9qC^ TE4kv-rr-^vAauYffFsssssuAASk6UE99E6RAitOM\n"+ - "NNOJv^^ -rr^^^^rCyvrr^^F6PXPkk2aAL|r^^^- ---rJv^-r2i^rrtIvr^^^rv^^^^^^^^^^^^rV2v^^^--^ckk5PkkPUmA^ ^EqP^ -fPsTxfFsszzzzjzjF7tlF2U6k6mqmbstOM\n"+ - "NNbJLr^rv|rrr^^uPS52Yv^-1PaA2eo2yzF|^- ----r2Trt7v^--- -^vv^^^^^^^^^|t2zr- --rCGU5kUUPkGPr- -eU|- -|oCsJIYYFssjzzjzjjYtlye22eSdOdpDstOM\n"+ - "NNbxi|vtu|rrrrv5hPkkytv|vV4e3eAejfeT- ^3jT||ir^-----^ir^^^^^--^I23oyuy4GGw5kEkPP5jr- --- -rv^ ^waFAAy442VujnnjsjyeyJv||LlYT|iyUbztOM\n"+ - "NQOJT|^|lrrrrrFEPUUolxteAya2sItloejv- -LeTr1vr^^^^^^|t^- -vSY^ -rLAUS4h542Ccr^-- ---- -- ^94CoZAye22AaAA2oAIrrriCFyXZkEAtJvr|tON\n"+ - "QQ8YtJLtTr^rrreGkEkjJtJ4S3Aw3TLvilyc- ^as|r|rrvrr1|Jl^ ^Ca|- -^Lyoe2ezcr^^^^- ------ ^Hk2ya5Z5S4w4oeey2Sr^JezTAaw9hSc^vzl7l8N\n"+ - "QQN08dZstL|rrr2Gk6kzt7sS2CA4Af|1||TL- -Torrvietrvir^- -vAIrrLzAaeCJ|r^^^^^^- ------ -ADSAVA2y2k5eCCCzFze|^TCESvr1rvlTT3PH80MQ\n"+ - "QQQQNNMRmVtTLvAmU6UjtcjAyuAAASu|rrv|- ^2z^^^^^^-- -rAI^ ------^--^^^-- ------ rDaSSS4ZU5yCy3jFFzsyirTCoXPoT||t2OgMNNQQQ\n"+ - "QQQQQQQNNRSxTvVdEGECJcsSojV4a5t^rrLr -LUr -r2u^- -----^^^^---- - ------ -om4S5SU62yooenszssf3t^|oneuTi7lUgMNNQQQQQ\n"+ - "QQQQQQQQNMgGlLT9qUG2x7JSS2zICSA^-Jx- ^eo^ -^yer- ------- - -- ---- ^Gk5kk9SFsnzuCCCe2225y^^jzPi^|J9gNNQQQQQQQ\n"+ - "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n"+ - "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; - - System.out.println(" _____________________________"+ - "_______________________________\n" + " Hey hey, I'm Sparkle!\n" + " _____________________________"+ - "_______________________________\n" + "\n" + logo); + String logo = + "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n" + + "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n" + + "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n" + + "QQQQQQNMMgmJiLTTtttttttttttTJX5Aaa444AA22o2AwU4S6PPkP5Pr^SSr^^^^^^^^^^^^^^^^^^rJ^" + + " --^vir^^^^^^rrr1|LtIuyeAOP2PUkZpBBBO954S5XPPkUE9666GGGUYtGgMMNQQQQQQ\n" + + "QQQQNNMMR5TL7TTTttTTT7cLLivv|ia42222oo2oeooooeoSPPkPPm|-tdEer^^^^^^^^^^^^^^^^^ir----" + + " ^r|v^^^^^rr|vLtFCe2AAHGeZPU5ARBBQqU4aS444SSSSSZ5wXPP5FcSRgMMNQQQQ\n" + + "QQNMgRH4JiLLLLivvvv||1rrrrrr^^LE5eoooooeoooooooeo4PhPk^^ko49e^^^^^^^^^^^^^^^^rJ^-----^7Trrvr^^rrr|vvi7tIzs9be2XPkZAURBR6h22AAAAAAAAAAAaaa44ettApRgMNNQ\n" + + "QQRAFTvvv|||rrrrrr^^^^^^^^^^rwevu95oeoeoeeeeeoooeeoaP4ioZooAkC^^^^^^^r|fASaoCAs------^yMHv^rvr^^^rrrrrr|||u8AVZXPEGGSOQqwaaAAAAAAA2AAA2AAAAAAostTI34RQ\n" + + "NQ8J|rrrrr^^^^^^^^^^^^^^^^^eZLTeU88Hmk5SZZ5S4aAAAo2a24LF5oo2Pkr-^rtoSAyA69UU5wT----" + + " -^2R0Q5r^||^^^^^^^^^^^rqEjAwXUGpUSRgh4A4SSSS4aAAAA22222o2222oeLLON\n" + + "NNOJ|^^^^^^^^^^^^^^^^^^^^vZIf98O6kPk9b88mGUkkkVr^rFousttA2oePPlomOO88dGkU88HHpi- " + + " -reRRRNEr^^F5t|r^^^^^-^kHey5wSaGau8Bq3tvctJYzCyeo22o22222222o27cbN\n" + + "NNOJ1^^^^^^^^^^^^^^^^^^^lyF6RbUUmpqG9kw5SSkkkC|3EkXS2ye4422PORRRRR888888OD88Hqv " + + " -ru88RRg9|^^rmmyXUzTvrrG82joSS3jzoRQR2i^rrrrr||viTJIzCVyeeeeeo7cbM\n" + + "NNOJ1^^^^^^^^^^^^^^^^^reyP88mmDEa2AAAaZwPPEUXkqE5Pk99kkUU68RRR8888888OdDO8O88Ov " + + " -^xO888R@kr^^^2gR8R8Fe8OUaujyASSA6qjaPt^-^^^^^^rrrrrr|vLtlIj42LcbM\n" + + "NNOJ1^^^^^^^^^^^^^^^^rXGH8Obmw22222Aa44ZXk6G9UUGmEZa46qO8R8888888ObO8888ObHHb8J- " + + " ^imR88R8f^^^--|mRR5vrv3PkaCje2SkHmYApPr------^^^^^^TA1rrrLUmJ|cbM\n" + + "NNOJr^^^^^^^^^^^^^^^^XQ8bR8ko2A22oo2AAAAAA2Aw9G9E6mUPGO888bHbbHH888HHHHHHbHHHOe- " + + " ^|PR88R4r^^--^^rVv-^^^--^rYuzC24w9PnkOr^^^^-------TPSe^^jEm5|r7bM\n" + + "NNOJr^^^^^^^^^^^^^^-|WWD8H42A2222o2AAAAAAAX66AC5myJw8R8888HHOHbbDdbObbOObHddpbP^ " + + " -rARO88x^^----^r^1v^- -^7jje45k998Gr^^^^^^^-^CZoy5ASGEm2^r7bM\n" + + "NNOJr^^^^^^^^^^^^^^-JB0pw2AA2222222AAa4PUP2jf26srsORR8808bOObO88RRgggRR8888888O| " + + " ----rj888Oj^^^^-^^^^^- - -^tyyA5PUmpC^^^^^^vyZ2o4UmG96UGe^r7bM\n" + + "NNOJ1^^^^^^^^^^^^^-^4RkA4ZZSSSSSZ5Zwkk5yIjCYyI^c8RRR88RR888ObbOO888OHddpppppH8Ra-" + + " ----^Lm8O8UJ^-----^|^ - -rTfoASXEmdy^^ru5SA5UGG9E9GESXx-^TOM\n" + + "NNOJr^^^^^^^^^^-^rJwkShkkPPPPPPPkPPS2C3eF1rTrrGNRR8OR0OGPkGH88888OHDDdppqqqpppbHr" + + " ----^rS8bO8moLr^^rTr -^v22e45kGqksCw4PEPAP6969E52eUT-rTOM\n" + + "NNOJr^^^^^^--^1f56kXkkPkPPPPPPwZ4SSA2jvr^|2^TWRRMgmoFs4m8RR88888HqmqpqppppppdHORa-" + + " ----^lHOdpqHy||x|- - -^ceLLyPPm9AAAAa2^^kG9hAee3Am3LctbM\n" + + "NNOJr^^^^-^T4k9EUEEkGmmGqpHOq6UwaAoyJvv|vA|eMWWmIrvS8gR88888R8pmmmmmmqdODpqpppdbHL-----^rkOmdUr-rrrr-" + + " --^rr^-^e2PGaoG9py-TmX2yyyC2q8bettbM\n" + + "NNOJr^^^^^----^^^^-^4QRbq6pqaoeeyyoVJTccEePMqs^^j8R88OO88888OpmGGGGp88OqmqDDppdHOpr" + + " ----^xPCo|-L|- ^^rLv^--rvfmGz4mkrrP4yyyVekq9EpRetbM\n" + + "NNOJr^^^^-----------uBRD6UdU2oeeye23fxLA8Gz^-|908bHHObqq8888HqmGGHRR8Hmp88dpdpppb8u-----rr---^^|r-" + + " -^vu7r^^^^rnm25s^|96kha2Ak6kE6mb3tbM\n" + + "NNDJ|^^^------------LQRpEGma2eeee2ACYj4ar-^C88OHbHO8PCER888OdmGHR8O8Hq88pmpDpqqqmdq|--^r-^vcvvr--------" + + " -^-^--^--rIpPoiFUwoyy3yyy3Cy3y2ItbM\n" + + "NMdJ1^--------------|MRGkmU22oeeoAA2Sl^-rkR8ObbHO8ktTUR8888Hqd88O88qD8dmqppqmmqmGqO9rr^^v7^-" + + " --^^^----- -^rr----^^repAzky||2233yyyyyyyyyxtbM\n" + + "NNbJ|^--------------rRRUPmw2AeyyAU4|--vSEASmpHb8pnvvlm8888Op88OO8bpb8pmmppqmmmmGGqHH9|rYr-" + + " --io|^--^^--IO2ySa9T^Jk42oeyyyyeoltbM\n" + + "NNbx|---------------^b8PPGa22y4ac^--^vLI46HHb885LvivivldRbH8bHO8HdbHdqmmppmGGG6GmDmpqwl^" + + " -^^^^rrv31^^J52Gq2o9v-zU5kkPwZSZhstbM\n" + + "NMpJ1---------------^k8ZkE24Uer-" + + " -^vAq8G6pH8R8ZzsJcivvvo6bDGHO8HqppHppmmpqGGGGGGmmmpqa^ - " + + " ^^Lr1|Sa4p8kC3oIxkSooAZk9E9jtbM\n" + + "NMmJr----------------AOahmUJ^--r2m8RHkEqdH8888RRRRdFvvvS8oJkd6mHpqpdppmqdqG6G996GUGGmkr" + + " --- - -^---rxCAmHO69kayokHpXS54aSFtbM\n" + + "NMqJr----------------jpqar-^tU80R88Aj9OpDOOO88888Rqt|7qHx|vvvsH8EEbHpGmqpqmGGG9G9GmU6E|" + + " ---- -- ---- ----^fSGmD9PkPZeCySmGP9mmutbM\n" + + "NMpJr----------------jC^^lm00R88RpIVbbDHHdDOOHHbb88AoR9ttCAyY9RmFa8Od6mpppqmGGmmEmGk9GJ-" + + " -^^-- ^vr^--- -------^AqPEPP5eAa2eeyAmpGmutbM\n" + + "NNHJr--------------r|^|U@0RRRRRNGc28HbHpqpObppHbbOEE8H9q888qpOOavIGp6eSqDpqqmmq6EmU9Eme^" + + " ^^^^^--- -rttTvr^- ---^ap24ae4woyeeeeyykDputbM\n" + + "NNOxr------------^|rtpR88888dqRPvA8dHDmmqODmmqdHpGq8pmbOObdH8bGI||vSz||smbpqppqk9P56E6Sr" + + " -^^^^^^^^^^^^----^^^^^^rrrvxI^- ---^A6j2ozyPPAyeeeeyy9OCtbM\n" + + "NNOJr-----------|tFpWR8qEwA3sPP|zHpppmGpbqmmqpDqmHbmmqpDpp8RHmGu||yS||v|c4ddpHmP6ee5UEPt^r7xFYlvr|r^^^^^rrr|LYeaPE69aIvvT-" + + " ---^SkjyFsAwkU52eyeeuAbytbM\n" + + "NNOJr---------^jA9pzrJ54aaozSP1lHpqpmGqqGGGGmpqmHq9U9mmGdmhppmpGntwjitIT||f42llkUnJt9EUPozovrl3CT^lGDqHOOpG5u7v|r|v|vsPa|-----^5Eoyt3wkkkUUk5ao3eqytbM\n" + + "NNbJr---------FpEv---jk4Sa3AUvTdbppmmpq6G6Gmqqmq95wUGk6qx^2O9pq6UmP5mGGGa7||vvzdwVT|XGUmkyev-^e2elCje2r^---" + + " ------^^-----^odUkfCPPkkkkkkUU4e6ytbM\n" + + "NMptr^-------vqt----^Ak44eaGvJ88ppqmbp69E9GmqmqkSk6UGqPTrtmPmGEUUG596kkk9ksvvLaH4yv|A62CV2yeFLs2Jr^rYoz^" + + " ---^^-----------------i8mO9FekUkkkkkkUPek3tbM\n" + + "NMptr^-------h|" + + " ----^5XSAaELC88DppqHH6EEE9GmmqkPkZXGC^--^5mm8GUhUUw9kPPPPk9PAyUp5oj4asyX99E4v^^jIrrrtje|^^^^-------------------^GRGwaeyPkUkkkkkk25jtbM\n" + + "NMpJr-------rJ------ikSA9UvaR8dpDpDbGEUUU9GGmqka56z^-- " + + " ^SSpOUGUGPPkPwZwwPU99Pm9PSUq4lCSXaoooCvjASS3Cui^^-----------------------tgPsooSo4EkPPPPP2astbM\n" + + "NNHJr ------rr---- -oEw8e|UROHHdqHOGUUUUU96mmZ5wt^- " + + " rkaaPh4ZUXP5waa4ZPPkXPpwPwkEU5oCeAkPCXf^Jo2r--- " + + " ----------------------|H8SyzC5aeXkPPkkA2ItbM\n" + + "NNbT^" + + " -------^-----|kqGcjR0bppDH8OG9UkkkUU9Dm4AUCr^-----vUofa5ASka5a422A455w4PmAZXSZ555X9U7e4CPUeePe^^-------------^^^rr^^^^---^5HH8ajuCo5aaPkkk4yJtbM\n" + + "NNbJr-------------^kHuFp0Rbpb8R88m69PU6GqmmHqGmpH8Oqkev^IPsTS425UASAA2y2Aaa4ePGoaZAaS4a4Sk1^4G4a5UqO888ROmmqG99mmpmGwyIv||v|r^^--^i6XuCyyya99PPkwCttbM\n" + + "NNOxr------------^eosGRRR88RRR88H6GUkkkE9mpm6PAoSbOObEGHpwvLk2ePkAAoooye22A2eZZ3AA2a4aa4ASv-^9pqG6GpDdOg8qqmmqmb888ROXSH86wVLrrr^roZ33yyyee2S6q9kATtOM\n" + + "NNbJr----------^ifyG8RRRRR88R888GGqkPPPPkGG6j^--vOma2aaA6mGUay2w4ooy3eyye2AoyFyCoAo2222SA2AztoDGH69mpd8ROppmmmmb8888mUc^e8dbRROPCCt7yeyeyeo22eSmpGltOM\n" + + "NNOJr-rr^^^rrijakp88888888888bmqEqmkPPwPU9lse^ " + + " vpsrrCS|zqpOXjAYJ2oCCCCCye22C|j3e2yeeee5Aat--^COOpU6mqO8DpdmGmDOR88qa2AuIy5q8R8Hzi7lyeeyeeo22o4k6jvtOM\n" + + "NNOxr--rJeX6mqH8ObOOO88888qPoja96bmPwXwPGX^^vi-" + + " ^ji^-^eAitZmPFCTrAAnjjuu3eeaI^teVoCyyyyooAz----n8O8pqmH8pppmmpb8888Vr^-^r|Js9WRRpCJuoeeeeo2222ADA-^tOM\n" + + "NNOJr-----^^^zmGGmH88GkdPyzjeA66mbmPwXwkmU^" + + " -^^--|F^-----^zL^r^--^vYeeyuny24|-|ay2VyyyeLL2o^ -^^SpqOHqdHqdpGmD8R88Ov- " + + " -^rr|TDW88Ujy2yyeeoAA2e5q| ^tOM\n" + + "NNbtr------^l2yoyC4Gk6mAyaw5aa9GpHmPwhhkqp^ - --^^r^r^-rT^ - -^rLC4G2^" + + " ^2nCCjyeAvr35|- --^kHpmmbppHmGpO88H85r^^^^r^^|l6g8ROAe2yeee24aeyGa^ rtOM\n" + + "NNOlt|^-^|A4eA423jZ6h9kS6kSaA4GmDbpk55Pkm2r ----- ----^-- " + + " --r^--^oX4w4A24GGZ5Sv^-^^vRpdqmGDpmpH88qp8yr^^^v^^r|ud8888pS2eeeo2SaVypJ- rtOM\n" + + "NNOxCGqEPaS969Z2njw9Pqp9UkwaeAqpHbH95Zw99Lr - - -L^ " + + " -rv|cXUZkhlzPPmpqqOP|^ebpH9mpmppO8mqpbui|r|fxLF4mq88888qAeeeoAh4uAk^ rtOM\n" + + "NNOJjPSAoyPmXkGmGk99mm99kS2eem8pHHbmw55G9||- " + + " ^E2TxAlF4SS9qmGmwufGd9GqmqmO8GG9HEZ2L2qFvt44PGH8O888EeeooaP4u4A^ rtOM\n" + + "NNOJF4SaSGm6XhPX45Gq66U55XSa6PqHpHHqPww9HPo^ " + + " ^Ir-^Je1|eP6x|oEEGUUEkmGmGp8E9EqqyC2PA5SavT5uoG8OOO8RGee24PSCZJ---rtOM\n" + + "NMHJT|vP8Gk9PXP5XmqmmGGUkkEE7|68mpppUwkG|^rr " + + " ^^-----^uGi--^Ska2PhEGG6pHPPk68wVo2A5Gus1LeAXA4GDHO8RHAoZPSyw|---rtOM\n" + + "NMDJ|LqHmGPEUhZkqpHqG99EEGAvTsCdqdpp6k9kr^^i^ -- " + + " --^^^^vvr--^teIvzkSP66Gpq55wkG6A22A4wquliteyye4wwXEqpO8Hkw42hr --rtOM\n" + + "NNHJybqmm65k65Ppbpaa9E9EmoLVv^^PRqqmm9Ukr^^r|- ------ -^-" + + " --^^^^rt|^-^jwSU99mqk4ZZPU6P2aaaSwmYjJtyyyeeee2hGGqb88RbkXr---rtOM\n" + + "NNbJ3qqm6E5aGwmO9ey5U99p2Lyr^^^v8OG6G6kkr^^^rr- - -- -^- " + + " - ----- -r45P99GmkAa44X55wS4S5SShEYaAlyyyyeeee2Zoe25E6m8qJr^-rtOM\n" + + "NMpJCmmG9kXeXGq92yy4kkqkt2|^^^^^j8mE9U5bT^^^^r|- - " + + " ---- ^jwhEGGE5AAAAAha2Z24S45XwkZy2ya3yyyeeooAw2eoa55wGy- --rtOM\n" + + "NMHJCmG9UPGyrkpaAyu259qLty^^^^^^^U8EEUwbGr^^^^rr^- --- " + + " --^rf59GGEka22AAAAwo3r|ooAa5XPEAwEt4eyyeeeeoAXAe245Zwp2- --rtOM\n" + + "NNOxCG9kP9o^-1mG2ynyap4rTj^^^^^^^LbGkEP9qu^^^^^^^|^ -- " + + " -^|itzo5UUPeie5a4AAaAAaPufr-^3CeAS5wwam8eu4Cyeeee2aPSe2S5w5Go- --rtOM\n" + + "NNOxuUkPmC^-^-|8q2YjaGF^vVr^^^^^^^zdEUX9kkt^^^^^^^r|- ------ " + + " --^|Iv^- ^PZZaAaAa5P3Ir -IyC2aZw4UG9EySCyeeeoA4Pwo2S5556S^ --rtOM\n" + + "NNOJjXk9t^-^^--rGGaz2klrrAv^^^^^^^^2qEP6mP6f^^^^^^|ke^- " + + " ^r1^^^rr1ySS4AAASPUAzr- veu2A4SUpkZG45ACyeeoa4XPA2S555k9| rtOM\n" + + "NNbJj9P|^-^^-- rmSaUUjrrJor^^^^^^^^SqUGkvv2Av^^^^YP|^r- " + + " -^|2i^^^^^^-chAa4A2wkU5ot^^-- |2C2A4kSy4UUZkhnyyeeaShk4ASwwwwG2- ^tOM\n" + + "NNbJVe^^^^^- --- ^Xko5Syv^xyrr^^^^^^^up9qF^rr^^^^|aer^^r^- " + + " ---^|IJrvUF^^^^^^^vS4AaawE999w1- ---^Joy2Ame-^r3m4kPjC3yea5Xkw4S5w5h9mv- ^tOM\n" + + "NNblv^^^^^--^--^^-^ekaS46Us4errr^^^^^^vkkkPCv||^^7hl^^^^^rr^----^^^r|v7xsCoaAIr^iGu^^^^^^^|aSAaPU9UEqe^" + + " -C2e2U3- -L^jEmPzyeo2SwwUPSSw5w9S3kr ^tOM\n" + + "NNOJvr^^^-rr-^^^----r5GkAwkUm4vrrr^^^^^ryPPj^^^" + + " -i4i^^^^^^^rtYJs2SA2eyy3jt1^^-^fEy^^^^^^^v4SAZPkUUmmL- ^5o2Ua^ " + + " ^vtGqmwZSaSZ44ZXkPkkUO9rfa-^tOM\n" + + "NNbtv^^^ r1^^^rr^----^yEPU9UX4PV|rr^^^^^-|zAki-" + + " -vAJ^^^^rr|JfT7i^^r^^^^^^^^^^^jUJ^^^^^^^Jk5ZhPhP9qC^ " + + " TE4kv-rr-^vAauYffFsssssuAASk6UE99E6RAitOM\n" + + "NNOJv^^ -rr^^^^rCyvrr^^F6PXPkk2aAL|r^^^-" + + " ---rJv^-r2i^rrtIvr^^^rv^^^^^^^^^^^^rV2v^^^--^ckk5PkkPUmA^ ^EqP^ " + + " -fPsTxfFsszzzzjzjF7tlF2U6k6mqmbstOM\n" + + "NNbJLr^rv|rrr^^uPS52Yv^-1PaA2eo2yzF|^- ----r2Trt7v^--- -^vv^^^^^^^^^|t2zr-" + + " --rCGU5kUUPkGPr- -eU|- -|oCsJIYYFssjzzjzjjYtlye22eSdOdpDstOM\n" + + "NNbxi|vtu|rrrrv5hPkkytv|vV4e3eAejfeT- " + + " ^3jT||ir^-----^ir^^^^^--^I23oyuy4GGw5kEkPP5jr- --- -rv^ " + + " ^waFAAy442VujnnjsjyeyJv||LlYT|iyUbztOM\n" + + "NQOJT|^|lrrrrrFEPUUolxteAya2sItloejv- -LeTr1vr^^^^^^|t^- -vSY^" + + " -rLAUS4h542Ccr^-- ---- -- ^94CoZAye22AaAA2oAIrrriCFyXZkEAtJvr|tON\n" + + "QQ8YtJLtTr^rrreGkEkjJtJ4S3Aw3TLvilyc- ^as|r|rrvrr1|Jl^ ^Ca|-" + + " -^Lyoe2ezcr^^^^- ------ ^Hk2ya5Z5S4w4oeey2Sr^JezTAaw9hSc^vzl7l8N\n" + + "QQN08dZstL|rrr2Gk6kzt7sS2CA4Af|1||TL- -Torrvietrvir^- " + + " -vAIrrLzAaeCJ|r^^^^^^- ------ " + + " -ADSAVA2y2k5eCCCzFze|^TCESvr1rvlTT3PH80MQ\n" + + "QQQQNNMRmVtTLvAmU6UjtcjAyuAAASu|rrv|- ^2z^^^^^^-- -rAI^ " + + " ------^--^^^-- ------ rDaSSS4ZU5yCy3jFFzsyirTCoXPoT||t2OgMNNQQQ\n" + + "QQQQQQQNNRSxTvVdEGECJcsSojV4a5t^rrLr -LUr -r2u^- -----^^^^----" + + " - ------ -om4S5SU62yooenszssf3t^|oneuTi7lUgMNNQQQQQ\n" + + "QQQQQQQQNMgGlLT9qUG2x7JSS2zICSA^-Jx- ^eo^ -^yer- ------- " + + " - -- ---- ^Gk5kk9SFsnzuCCCe2225y^^jzPi^|J9gNNQQQQQQQ\n" + + "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n" + + "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; - System.out.println(" _____________________________"+ - "_______________________________\n" + - " Got any cool, daring quests or risky biz? Just hit me up!\n"+ - " _____________________________"+ - "_______________________________\n"); + System.out.println( + " _____________________________" + + "_______________________________\n" + + " Hey hey, I'm Sparkle!\n" + + " _____________________________" + + "_______________________________\n" + + "\n" + + logo); - String userInput = scanner.nextLine(); - while(!userInput.equalsIgnoreCase("bye")){ - System.out.println(" _________________________________"+ - "___________________________\n"+ - " "+ - userInput+ "~" + - "\n"+ - " _________________________________"+ - "___________________________\n"); - userInput = scanner.nextLine(); + System.out.println( + " _____________________________" + + "_______________________________\n" + + " Got any cool, daring quests or risky biz? Just hit me up!\n" + + " _____________________________" + + "_______________________________\n"); + + Task[] tasks = new Task[100]; + int taskCount = 0; + + String userInput = scanner.nextLine(); + while (!userInput.equalsIgnoreCase("bye")) { + if (userInput.equalsIgnoreCase("list")) { + System.out.println( + " _________________________________" + "___________________________\n"); + if (taskCount == 0) { + System.out.println(" Looks like there's nothing fun to mess with... How boring!"); + } else { + for (int i = 0; i < taskCount; i++) { + System.out.println( + " " + + (i + 1) + + ". [" + + tasks[i].getStatusIcon() + + "] " + + tasks[i].description + + "~♪"); + } + } + System.out.println( + " _________________________________" + "___________________________\n"); + } else if (userInput.startsWith("mark")) { + int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; + if (taskNumber >= 0 && taskNumber < taskCount) { + tasks[taskNumber].markAsDone(); + System.out.println( + " _____________________________" + + "_______________________________\n" + + " Boom! Task's done and dusted~\n" + + " [" + + tasks[taskNumber].getStatusIcon() + + "] " + + tasks[taskNumber].description + + "\n" + + " _____________________________" + + "_______________________________\n"); + } else { + System.out.println( + " _____________________________" + + "_______________________________\n" + + " That task number's playing hide and seek—try again!.\n" + + " _____________________________" + + "_______________________________\n"); } - - System.out.println(" _________________________________"+ - "___________________________\n" + - " See you around, Stelle~ Try to stay out of trouble, especially... the next time we meet!\n" + - " _________________________________"+ - "___________________________\n"); - scanner.close(); + } else if (userInput.startsWith("unmark")) { + int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; + if (taskNumber >= 0 && taskNumber < taskCount) { + tasks[taskNumber].markAsUndone(); + System.out.println( + " _____________________________" + + "_______________________________\n" + + " Oops! Not done yet, but it's still on the radar!\n" + + " [" + + tasks[taskNumber].getStatusIcon() + + "] " + + tasks[taskNumber].description + + "\n" + + " _____________________________" + + "_______________________________\n"); + } else { + System.out.println( + " _____________________________" + + "_______________________________\n" + + " That task number's playing hide and seek—try again!\n" + + " _____________________________" + + "_______________________________\n"); + } + } else { + // Add the task if it's not "list" + tasks[taskCount] = new Task(userInput); + taskCount++; + System.out.println( + " _____________________________" + + "_______________________________\n" + + " added: " + + userInput + + "! Let\'s make it fun~" + + "\n" + + " _____________________________" + + "_______________________________\n"); + } + userInput = scanner.nextLine(); } -} \ No newline at end of file + + System.out.println( + " ____________________________________________________________\n" + + " See you around, Stelle~ Try to stay out of trouble, especially... the next time" + + " we meet!\n" + + " ____________________________________________________________\n"); + scanner.close(); + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 0e1d775a0..3be2b901f 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -14,4 +14,10 @@ public String getStatusIcon() { public void markAsDone() { this.isDone = true; } + + public void markAsUndone() { + this.isDone = false; + } + + } \ No newline at end of file From 04395740ebab39d9bf5a4ef0c250cc9a5bd6f05d Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 03:58:02 +0800 Subject: [PATCH 07/43] Revert "Add markAsUndone method to enable unchecking" This reverts commit fc8da49a00110ebf80b39cbe2a0cb68014558a85. --- src/main/java/Sparkle.java | 362 +++++++++++-------------------------- src/main/java/Task.java | 6 - 2 files changed, 104 insertions(+), 264 deletions(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index 5ecbfc48f..1e608101a 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -1,266 +1,112 @@ import java.util.Scanner; public class Sparkle { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); - String logo = - "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n" - + "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n" - + "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n" - + "QQQQQQNMMgmJiLTTtttttttttttTJX5Aaa444AA22o2AwU4S6PPkP5Pr^SSr^^^^^^^^^^^^^^^^^^rJ^" - + " --^vir^^^^^^rrr1|LtIuyeAOP2PUkZpBBBO954S5XPPkUE9666GGGUYtGgMMNQQQQQQ\n" - + "QQQQNNMMR5TL7TTTttTTT7cLLivv|ia42222oo2oeooooeoSPPkPPm|-tdEer^^^^^^^^^^^^^^^^^ir----" - + " ^r|v^^^^^rr|vLtFCe2AAHGeZPU5ARBBQqU4aS444SSSSSZ5wXPP5FcSRgMMNQQQQ\n" - + "QQNMgRH4JiLLLLivvvv||1rrrrrr^^LE5eoooooeoooooooeo4PhPk^^ko49e^^^^^^^^^^^^^^^^rJ^-----^7Trrvr^^rrr|vvi7tIzs9be2XPkZAURBR6h22AAAAAAAAAAAaaa44ettApRgMNNQ\n" - + "QQRAFTvvv|||rrrrrr^^^^^^^^^^rwevu95oeoeoeeeeeoooeeoaP4ioZooAkC^^^^^^^r|fASaoCAs------^yMHv^rvr^^^rrrrrr|||u8AVZXPEGGSOQqwaaAAAAAAA2AAA2AAAAAAostTI34RQ\n" - + "NQ8J|rrrrr^^^^^^^^^^^^^^^^^eZLTeU88Hmk5SZZ5S4aAAAo2a24LF5oo2Pkr-^rtoSAyA69UU5wT----" - + " -^2R0Q5r^||^^^^^^^^^^^rqEjAwXUGpUSRgh4A4SSSS4aAAAA22222o2222oeLLON\n" - + "NNOJ|^^^^^^^^^^^^^^^^^^^^vZIf98O6kPk9b88mGUkkkVr^rFousttA2oePPlomOO88dGkU88HHpi- " - + " -reRRRNEr^^F5t|r^^^^^-^kHey5wSaGau8Bq3tvctJYzCyeo22o22222222o27cbN\n" - + "NNOJ1^^^^^^^^^^^^^^^^^^^lyF6RbUUmpqG9kw5SSkkkC|3EkXS2ye4422PORRRRR888888OD88Hqv " - + " -ru88RRg9|^^rmmyXUzTvrrG82joSS3jzoRQR2i^rrrrr||viTJIzCVyeeeeeo7cbM\n" - + "NNOJ1^^^^^^^^^^^^^^^^^reyP88mmDEa2AAAaZwPPEUXkqE5Pk99kkUU68RRR8888888OdDO8O88Ov " - + " -^xO888R@kr^^^2gR8R8Fe8OUaujyASSA6qjaPt^-^^^^^^rrrrrr|vLtlIj42LcbM\n" - + "NNOJ1^^^^^^^^^^^^^^^^rXGH8Obmw22222Aa44ZXk6G9UUGmEZa46qO8R8888888ObO8888ObHHb8J- " - + " ^imR88R8f^^^--|mRR5vrv3PkaCje2SkHmYApPr------^^^^^^TA1rrrLUmJ|cbM\n" - + "NNOJr^^^^^^^^^^^^^^^^XQ8bR8ko2A22oo2AAAAAA2Aw9G9E6mUPGO888bHbbHH888HHHHHHbHHHOe- " - + " ^|PR88R4r^^--^^rVv-^^^--^rYuzC24w9PnkOr^^^^-------TPSe^^jEm5|r7bM\n" - + "NNOJr^^^^^^^^^^^^^^-|WWD8H42A2222o2AAAAAAAX66AC5myJw8R8888HHOHbbDdbObbOObHddpbP^ " - + " -rARO88x^^----^r^1v^- -^7jje45k998Gr^^^^^^^-^CZoy5ASGEm2^r7bM\n" - + "NNOJr^^^^^^^^^^^^^^-JB0pw2AA2222222AAa4PUP2jf26srsORR8808bOObO88RRgggRR8888888O| " - + " ----rj888Oj^^^^-^^^^^- - -^tyyA5PUmpC^^^^^^vyZ2o4UmG96UGe^r7bM\n" - + "NNOJ1^^^^^^^^^^^^^-^4RkA4ZZSSSSSZ5Zwkk5yIjCYyI^c8RRR88RR888ObbOO888OHddpppppH8Ra-" - + " ----^Lm8O8UJ^-----^|^ - -rTfoASXEmdy^^ru5SA5UGG9E9GESXx-^TOM\n" - + "NNOJr^^^^^^^^^^-^rJwkShkkPPPPPPPkPPS2C3eF1rTrrGNRR8OR0OGPkGH88888OHDDdppqqqpppbHr" - + " ----^rS8bO8moLr^^rTr -^v22e45kGqksCw4PEPAP6969E52eUT-rTOM\n" - + "NNOJr^^^^^^--^1f56kXkkPkPPPPPPwZ4SSA2jvr^|2^TWRRMgmoFs4m8RR88888HqmqpqppppppdHORa-" - + " ----^lHOdpqHy||x|- - -^ceLLyPPm9AAAAa2^^kG9hAee3Am3LctbM\n" - + "NNOJr^^^^-^T4k9EUEEkGmmGqpHOq6UwaAoyJvv|vA|eMWWmIrvS8gR88888R8pmmmmmmqdODpqpppdbHL-----^rkOmdUr-rrrr-" - + " --^rr^-^e2PGaoG9py-TmX2yyyC2q8bettbM\n" - + "NNOJr^^^^^----^^^^-^4QRbq6pqaoeeyyoVJTccEePMqs^^j8R88OO88888OpmGGGGp88OqmqDDppdHOpr" - + " ----^xPCo|-L|- ^^rLv^--rvfmGz4mkrrP4yyyVekq9EpRetbM\n" - + "NNOJr^^^^-----------uBRD6UdU2oeeye23fxLA8Gz^-|908bHHObqq8888HqmGGHRR8Hmp88dpdpppb8u-----rr---^^|r-" - + " -^vu7r^^^^rnm25s^|96kha2Ak6kE6mb3tbM\n" - + "NNDJ|^^^------------LQRpEGma2eeee2ACYj4ar-^C88OHbHO8PCER888OdmGHR8O8Hq88pmpDpqqqmdq|--^r-^vcvvr--------" - + " -^-^--^--rIpPoiFUwoyy3yyy3Cy3y2ItbM\n" - + "NMdJ1^--------------|MRGkmU22oeeoAA2Sl^-rkR8ObbHO8ktTUR8888Hqd88O88qD8dmqppqmmqmGqO9rr^^v7^-" - + " --^^^----- -^rr----^^repAzky||2233yyyyyyyyyxtbM\n" - + "NNbJ|^--------------rRRUPmw2AeyyAU4|--vSEASmpHb8pnvvlm8888Op88OO8bpb8pmmppqmmmmGGqHH9|rYr-" - + " --io|^--^^--IO2ySa9T^Jk42oeyyyyeoltbM\n" - + "NNbx|---------------^b8PPGa22y4ac^--^vLI46HHb885LvivivldRbH8bHO8HdbHdqmmppmGGG6GmDmpqwl^" - + " -^^^^rrv31^^J52Gq2o9v-zU5kkPwZSZhstbM\n" - + "NMpJ1---------------^k8ZkE24Uer-" - + " -^vAq8G6pH8R8ZzsJcivvvo6bDGHO8HqppHppmmpqGGGGGGmmmpqa^ - " - + " ^^Lr1|Sa4p8kC3oIxkSooAZk9E9jtbM\n" - + "NMmJr----------------AOahmUJ^--r2m8RHkEqdH8888RRRRdFvvvS8oJkd6mHpqpdppmqdqG6G996GUGGmkr" - + " --- - -^---rxCAmHO69kayokHpXS54aSFtbM\n" - + "NMqJr----------------jpqar-^tU80R88Aj9OpDOOO88888Rqt|7qHx|vvvsH8EEbHpGmqpqmGGG9G9GmU6E|" - + " ---- -- ---- ----^fSGmD9PkPZeCySmGP9mmutbM\n" - + "NMpJr----------------jC^^lm00R88RpIVbbDHHdDOOHHbb88AoR9ttCAyY9RmFa8Od6mpppqmGGmmEmGk9GJ-" - + " -^^-- ^vr^--- -------^AqPEPP5eAa2eeyAmpGmutbM\n" - + "NNHJr--------------r|^|U@0RRRRRNGc28HbHpqpObppHbbOEE8H9q888qpOOavIGp6eSqDpqqmmq6EmU9Eme^" - + " ^^^^^--- -rttTvr^- ---^ap24ae4woyeeeeyykDputbM\n" - + "NNOxr------------^|rtpR88888dqRPvA8dHDmmqODmmqdHpGq8pmbOObdH8bGI||vSz||smbpqppqk9P56E6Sr" - + " -^^^^^^^^^^^^----^^^^^^rrrvxI^- ---^A6j2ozyPPAyeeeeyy9OCtbM\n" - + "NNOJr-----------|tFpWR8qEwA3sPP|zHpppmGpbqmmqpDqmHbmmqpDpp8RHmGu||yS||v|c4ddpHmP6ee5UEPt^r7xFYlvr|r^^^^^rrr|LYeaPE69aIvvT-" - + " ---^SkjyFsAwkU52eyeeuAbytbM\n" - + "NNOJr---------^jA9pzrJ54aaozSP1lHpqpmGqqGGGGmpqmHq9U9mmGdmhppmpGntwjitIT||f42llkUnJt9EUPozovrl3CT^lGDqHOOpG5u7v|r|v|vsPa|-----^5Eoyt3wkkkUUk5ao3eqytbM\n" - + "NNbJr---------FpEv---jk4Sa3AUvTdbppmmpq6G6Gmqqmq95wUGk6qx^2O9pq6UmP5mGGGa7||vvzdwVT|XGUmkyev-^e2elCje2r^---" - + " ------^^-----^odUkfCPPkkkkkkUU4e6ytbM\n" - + "NMptr^-------vqt----^Ak44eaGvJ88ppqmbp69E9GmqmqkSk6UGqPTrtmPmGEUUG596kkk9ksvvLaH4yv|A62CV2yeFLs2Jr^rYoz^" - + " ---^^-----------------i8mO9FekUkkkkkkUPek3tbM\n" - + "NMptr^-------h|" - + " ----^5XSAaELC88DppqHH6EEE9GmmqkPkZXGC^--^5mm8GUhUUw9kPPPPk9PAyUp5oj4asyX99E4v^^jIrrrtje|^^^^-------------------^GRGwaeyPkUkkkkkk25jtbM\n" - + "NMpJr-------rJ------ikSA9UvaR8dpDpDbGEUUU9GGmqka56z^-- " - + " ^SSpOUGUGPPkPwZwwPU99Pm9PSUq4lCSXaoooCvjASS3Cui^^-----------------------tgPsooSo4EkPPPPP2astbM\n" - + "NNHJr ------rr---- -oEw8e|UROHHdqHOGUUUUU96mmZ5wt^- " - + " rkaaPh4ZUXP5waa4ZPPkXPpwPwkEU5oCeAkPCXf^Jo2r--- " - + " ----------------------|H8SyzC5aeXkPPkkA2ItbM\n" - + "NNbT^" - + " -------^-----|kqGcjR0bppDH8OG9UkkkUU9Dm4AUCr^-----vUofa5ASka5a422A455w4PmAZXSZ555X9U7e4CPUeePe^^-------------^^^rr^^^^---^5HH8ajuCo5aaPkkk4yJtbM\n" - + "NNbJr-------------^kHuFp0Rbpb8R88m69PU6GqmmHqGmpH8Oqkev^IPsTS425UASAA2y2Aaa4ePGoaZAaS4a4Sk1^4G4a5UqO888ROmmqG99mmpmGwyIv||v|r^^--^i6XuCyyya99PPkwCttbM\n" - + "NNOxr------------^eosGRRR88RRR88H6GUkkkE9mpm6PAoSbOObEGHpwvLk2ePkAAoooye22A2eZZ3AA2a4aa4ASv-^9pqG6GpDdOg8qqmmqmb888ROXSH86wVLrrr^roZ33yyyee2S6q9kATtOM\n" - + "NNbJr----------^ifyG8RRRRR88R888GGqkPPPPkGG6j^--vOma2aaA6mGUay2w4ooy3eyye2AoyFyCoAo2222SA2AztoDGH69mpd8ROppmmmmb8888mUc^e8dbRROPCCt7yeyeyeo22eSmpGltOM\n" - + "NNOJr-rr^^^rrijakp88888888888bmqEqmkPPwPU9lse^ " - + " vpsrrCS|zqpOXjAYJ2oCCCCCye22C|j3e2yeeee5Aat--^COOpU6mqO8DpdmGmDOR88qa2AuIy5q8R8Hzi7lyeeyeeo22o4k6jvtOM\n" - + "NNOxr--rJeX6mqH8ObOOO88888qPoja96bmPwXwPGX^^vi-" - + " ^ji^-^eAitZmPFCTrAAnjjuu3eeaI^teVoCyyyyooAz----n8O8pqmH8pppmmpb8888Vr^-^r|Js9WRRpCJuoeeeeo2222ADA-^tOM\n" - + "NNOJr-----^^^zmGGmH88GkdPyzjeA66mbmPwXwkmU^" - + " -^^--|F^-----^zL^r^--^vYeeyuny24|-|ay2VyyyeLL2o^ -^^SpqOHqdHqdpGmD8R88Ov- " - + " -^rr|TDW88Ujy2yyeeoAA2e5q| ^tOM\n" - + "NNbtr------^l2yoyC4Gk6mAyaw5aa9GpHmPwhhkqp^ - --^^r^r^-rT^ - -^rLC4G2^" - + " ^2nCCjyeAvr35|- --^kHpmmbppHmGpO88H85r^^^^r^^|l6g8ROAe2yeee24aeyGa^ rtOM\n" - + "NNOlt|^-^|A4eA423jZ6h9kS6kSaA4GmDbpk55Pkm2r ----- ----^-- " - + " --r^--^oX4w4A24GGZ5Sv^-^^vRpdqmGDpmpH88qp8yr^^^v^^r|ud8888pS2eeeo2SaVypJ- rtOM\n" - + "NNOxCGqEPaS969Z2njw9Pqp9UkwaeAqpHbH95Zw99Lr - - -L^ " - + " -rv|cXUZkhlzPPmpqqOP|^ebpH9mpmppO8mqpbui|r|fxLF4mq88888qAeeeoAh4uAk^ rtOM\n" - + "NNOJjPSAoyPmXkGmGk99mm99kS2eem8pHHbmw55G9||- " - + " ^E2TxAlF4SS9qmGmwufGd9GqmqmO8GG9HEZ2L2qFvt44PGH8O888EeeooaP4u4A^ rtOM\n" - + "NNOJF4SaSGm6XhPX45Gq66U55XSa6PqHpHHqPww9HPo^ " - + " ^Ir-^Je1|eP6x|oEEGUUEkmGmGp8E9EqqyC2PA5SavT5uoG8OOO8RGee24PSCZJ---rtOM\n" - + "NMHJT|vP8Gk9PXP5XmqmmGGUkkEE7|68mpppUwkG|^rr " - + " ^^-----^uGi--^Ska2PhEGG6pHPPk68wVo2A5Gus1LeAXA4GDHO8RHAoZPSyw|---rtOM\n" - + "NMDJ|LqHmGPEUhZkqpHqG99EEGAvTsCdqdpp6k9kr^^i^ -- " - + " --^^^^vvr--^teIvzkSP66Gpq55wkG6A22A4wquliteyye4wwXEqpO8Hkw42hr --rtOM\n" - + "NNHJybqmm65k65Ppbpaa9E9EmoLVv^^PRqqmm9Ukr^^r|- ------ -^-" - + " --^^^^rt|^-^jwSU99mqk4ZZPU6P2aaaSwmYjJtyyyeeee2hGGqb88RbkXr---rtOM\n" - + "NNbJ3qqm6E5aGwmO9ey5U99p2Lyr^^^v8OG6G6kkr^^^rr- - -- -^- " - + " - ----- -r45P99GmkAa44X55wS4S5SShEYaAlyyyyeeee2Zoe25E6m8qJr^-rtOM\n" - + "NMpJCmmG9kXeXGq92yy4kkqkt2|^^^^^j8mE9U5bT^^^^r|- - " - + " ---- ^jwhEGGE5AAAAAha2Z24S45XwkZy2ya3yyyeeooAw2eoa55wGy- --rtOM\n" - + "NMHJCmG9UPGyrkpaAyu259qLty^^^^^^^U8EEUwbGr^^^^rr^- --- " - + " --^rf59GGEka22AAAAwo3r|ooAa5XPEAwEt4eyyeeeeoAXAe245Zwp2- --rtOM\n" - + "NNOxCG9kP9o^-1mG2ynyap4rTj^^^^^^^LbGkEP9qu^^^^^^^|^ -- " - + " -^|itzo5UUPeie5a4AAaAAaPufr-^3CeAS5wwam8eu4Cyeeee2aPSe2S5w5Go- --rtOM\n" - + "NNOxuUkPmC^-^-|8q2YjaGF^vVr^^^^^^^zdEUX9kkt^^^^^^^r|- ------ " - + " --^|Iv^- ^PZZaAaAa5P3Ir -IyC2aZw4UG9EySCyeeeoA4Pwo2S5556S^ --rtOM\n" - + "NNOJjXk9t^-^^--rGGaz2klrrAv^^^^^^^^2qEP6mP6f^^^^^^|ke^- " - + " ^r1^^^rr1ySS4AAASPUAzr- veu2A4SUpkZG45ACyeeoa4XPA2S555k9| rtOM\n" - + "NNbJj9P|^-^^-- rmSaUUjrrJor^^^^^^^^SqUGkvv2Av^^^^YP|^r- " - + " -^|2i^^^^^^-chAa4A2wkU5ot^^-- |2C2A4kSy4UUZkhnyyeeaShk4ASwwwwG2- ^tOM\n" - + "NNbJVe^^^^^- --- ^Xko5Syv^xyrr^^^^^^^up9qF^rr^^^^|aer^^r^- " - + " ---^|IJrvUF^^^^^^^vS4AaawE999w1- ---^Joy2Ame-^r3m4kPjC3yea5Xkw4S5w5h9mv- ^tOM\n" - + "NNblv^^^^^--^--^^-^ekaS46Us4errr^^^^^^vkkkPCv||^^7hl^^^^^rr^----^^^r|v7xsCoaAIr^iGu^^^^^^^|aSAaPU9UEqe^" - + " -C2e2U3- -L^jEmPzyeo2SwwUPSSw5w9S3kr ^tOM\n" - + "NNOJvr^^^-rr-^^^----r5GkAwkUm4vrrr^^^^^ryPPj^^^" - + " -i4i^^^^^^^rtYJs2SA2eyy3jt1^^-^fEy^^^^^^^v4SAZPkUUmmL- ^5o2Ua^ " - + " ^vtGqmwZSaSZ44ZXkPkkUO9rfa-^tOM\n" - + "NNbtv^^^ r1^^^rr^----^yEPU9UX4PV|rr^^^^^-|zAki-" - + " -vAJ^^^^rr|JfT7i^^r^^^^^^^^^^^jUJ^^^^^^^Jk5ZhPhP9qC^ " - + " TE4kv-rr-^vAauYffFsssssuAASk6UE99E6RAitOM\n" - + "NNOJv^^ -rr^^^^rCyvrr^^F6PXPkk2aAL|r^^^-" - + " ---rJv^-r2i^rrtIvr^^^rv^^^^^^^^^^^^rV2v^^^--^ckk5PkkPUmA^ ^EqP^ " - + " -fPsTxfFsszzzzjzjF7tlF2U6k6mqmbstOM\n" - + "NNbJLr^rv|rrr^^uPS52Yv^-1PaA2eo2yzF|^- ----r2Trt7v^--- -^vv^^^^^^^^^|t2zr-" - + " --rCGU5kUUPkGPr- -eU|- -|oCsJIYYFssjzzjzjjYtlye22eSdOdpDstOM\n" - + "NNbxi|vtu|rrrrv5hPkkytv|vV4e3eAejfeT- " - + " ^3jT||ir^-----^ir^^^^^--^I23oyuy4GGw5kEkPP5jr- --- -rv^ " - + " ^waFAAy442VujnnjsjyeyJv||LlYT|iyUbztOM\n" - + "NQOJT|^|lrrrrrFEPUUolxteAya2sItloejv- -LeTr1vr^^^^^^|t^- -vSY^" - + " -rLAUS4h542Ccr^-- ---- -- ^94CoZAye22AaAA2oAIrrriCFyXZkEAtJvr|tON\n" - + "QQ8YtJLtTr^rrreGkEkjJtJ4S3Aw3TLvilyc- ^as|r|rrvrr1|Jl^ ^Ca|-" - + " -^Lyoe2ezcr^^^^- ------ ^Hk2ya5Z5S4w4oeey2Sr^JezTAaw9hSc^vzl7l8N\n" - + "QQN08dZstL|rrr2Gk6kzt7sS2CA4Af|1||TL- -Torrvietrvir^- " - + " -vAIrrLzAaeCJ|r^^^^^^- ------ " - + " -ADSAVA2y2k5eCCCzFze|^TCESvr1rvlTT3PH80MQ\n" - + "QQQQNNMRmVtTLvAmU6UjtcjAyuAAASu|rrv|- ^2z^^^^^^-- -rAI^ " - + " ------^--^^^-- ------ rDaSSS4ZU5yCy3jFFzsyirTCoXPoT||t2OgMNNQQQ\n" - + "QQQQQQQNNRSxTvVdEGECJcsSojV4a5t^rrLr -LUr -r2u^- -----^^^^----" - + " - ------ -om4S5SU62yooenszssf3t^|oneuTi7lUgMNNQQQQQ\n" - + "QQQQQQQQNMgGlLT9qUG2x7JSS2zICSA^-Jx- ^eo^ -^yer- ------- " - + " - -- ---- ^Gk5kk9SFsnzuCCCe2225y^^jzPi^|J9gNNQQQQQQQ\n" - + "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n" - + "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; + String logo = "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n"+ + "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n"+ + "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n"+ + "QQQQQQNMMgmJiLTTtttttttttttTJX5Aaa444AA22o2AwU4S6PPkP5Pr^SSr^^^^^^^^^^^^^^^^^^rJ^ --^vir^^^^^^rrr1|LtIuyeAOP2PUkZpBBBO954S5XPPkUE9666GGGUYtGgMMNQQQQQQ\n"+ + "QQQQNNMMR5TL7TTTttTTT7cLLivv|ia42222oo2oeooooeoSPPkPPm|-tdEer^^^^^^^^^^^^^^^^^ir---- ^r|v^^^^^rr|vLtFCe2AAHGeZPU5ARBBQqU4aS444SSSSSZ5wXPP5FcSRgMMNQQQQ\n"+ + "QQNMgRH4JiLLLLivvvv||1rrrrrr^^LE5eoooooeoooooooeo4PhPk^^ko49e^^^^^^^^^^^^^^^^rJ^-----^7Trrvr^^rrr|vvi7tIzs9be2XPkZAURBR6h22AAAAAAAAAAAaaa44ettApRgMNNQ\n"+ + "QQRAFTvvv|||rrrrrr^^^^^^^^^^rwevu95oeoeoeeeeeoooeeoaP4ioZooAkC^^^^^^^r|fASaoCAs------^yMHv^rvr^^^rrrrrr|||u8AVZXPEGGSOQqwaaAAAAAAA2AAA2AAAAAAostTI34RQ\n"+ + "NQ8J|rrrrr^^^^^^^^^^^^^^^^^eZLTeU88Hmk5SZZ5S4aAAAo2a24LF5oo2Pkr-^rtoSAyA69UU5wT---- -^2R0Q5r^||^^^^^^^^^^^rqEjAwXUGpUSRgh4A4SSSS4aAAAA22222o2222oeLLON\n"+ + "NNOJ|^^^^^^^^^^^^^^^^^^^^vZIf98O6kPk9b88mGUkkkVr^rFousttA2oePPlomOO88dGkU88HHpi- -reRRRNEr^^F5t|r^^^^^-^kHey5wSaGau8Bq3tvctJYzCyeo22o22222222o27cbN\n"+ + "NNOJ1^^^^^^^^^^^^^^^^^^^lyF6RbUUmpqG9kw5SSkkkC|3EkXS2ye4422PORRRRR888888OD88Hqv -ru88RRg9|^^rmmyXUzTvrrG82joSS3jzoRQR2i^rrrrr||viTJIzCVyeeeeeo7cbM\n"+ + "NNOJ1^^^^^^^^^^^^^^^^^reyP88mmDEa2AAAaZwPPEUXkqE5Pk99kkUU68RRR8888888OdDO8O88Ov -^xO888R@kr^^^2gR8R8Fe8OUaujyASSA6qjaPt^-^^^^^^rrrrrr|vLtlIj42LcbM\n"+ + "NNOJ1^^^^^^^^^^^^^^^^rXGH8Obmw22222Aa44ZXk6G9UUGmEZa46qO8R8888888ObO8888ObHHb8J- ^imR88R8f^^^--|mRR5vrv3PkaCje2SkHmYApPr------^^^^^^TA1rrrLUmJ|cbM\n"+ + "NNOJr^^^^^^^^^^^^^^^^XQ8bR8ko2A22oo2AAAAAA2Aw9G9E6mUPGO888bHbbHH888HHHHHHbHHHOe- ^|PR88R4r^^--^^rVv-^^^--^rYuzC24w9PnkOr^^^^-------TPSe^^jEm5|r7bM\n"+ + "NNOJr^^^^^^^^^^^^^^-|WWD8H42A2222o2AAAAAAAX66AC5myJw8R8888HHOHbbDdbObbOObHddpbP^ -rARO88x^^----^r^1v^- -^7jje45k998Gr^^^^^^^-^CZoy5ASGEm2^r7bM\n"+ + "NNOJr^^^^^^^^^^^^^^-JB0pw2AA2222222AAa4PUP2jf26srsORR8808bOObO88RRgggRR8888888O| ----rj888Oj^^^^-^^^^^- - -^tyyA5PUmpC^^^^^^vyZ2o4UmG96UGe^r7bM\n"+ + "NNOJ1^^^^^^^^^^^^^-^4RkA4ZZSSSSSZ5Zwkk5yIjCYyI^c8RRR88RR888ObbOO888OHddpppppH8Ra- ----^Lm8O8UJ^-----^|^ - -rTfoASXEmdy^^ru5SA5UGG9E9GESXx-^TOM\n"+ + "NNOJr^^^^^^^^^^-^rJwkShkkPPPPPPPkPPS2C3eF1rTrrGNRR8OR0OGPkGH88888OHDDdppqqqpppbHr ----^rS8bO8moLr^^rTr -^v22e45kGqksCw4PEPAP6969E52eUT-rTOM\n"+ + "NNOJr^^^^^^--^1f56kXkkPkPPPPPPwZ4SSA2jvr^|2^TWRRMgmoFs4m8RR88888HqmqpqppppppdHORa- ----^lHOdpqHy||x|- - -^ceLLyPPm9AAAAa2^^kG9hAee3Am3LctbM\n"+ + "NNOJr^^^^-^T4k9EUEEkGmmGqpHOq6UwaAoyJvv|vA|eMWWmIrvS8gR88888R8pmmmmmmqdODpqpppdbHL-----^rkOmdUr-rrrr- --^rr^-^e2PGaoG9py-TmX2yyyC2q8bettbM\n"+ + "NNOJr^^^^^----^^^^-^4QRbq6pqaoeeyyoVJTccEePMqs^^j8R88OO88888OpmGGGGp88OqmqDDppdHOpr ----^xPCo|-L|- ^^rLv^--rvfmGz4mkrrP4yyyVekq9EpRetbM\n"+ + "NNOJr^^^^-----------uBRD6UdU2oeeye23fxLA8Gz^-|908bHHObqq8888HqmGGHRR8Hmp88dpdpppb8u-----rr---^^|r- -^vu7r^^^^rnm25s^|96kha2Ak6kE6mb3tbM\n"+ + "NNDJ|^^^------------LQRpEGma2eeee2ACYj4ar-^C88OHbHO8PCER888OdmGHR8O8Hq88pmpDpqqqmdq|--^r-^vcvvr-------- -^-^--^--rIpPoiFUwoyy3yyy3Cy3y2ItbM\n"+ + "NMdJ1^--------------|MRGkmU22oeeoAA2Sl^-rkR8ObbHO8ktTUR8888Hqd88O88qD8dmqppqmmqmGqO9rr^^v7^- --^^^----- -^rr----^^repAzky||2233yyyyyyyyyxtbM\n"+ + "NNbJ|^--------------rRRUPmw2AeyyAU4|--vSEASmpHb8pnvvlm8888Op88OO8bpb8pmmppqmmmmGGqHH9|rYr- --io|^--^^--IO2ySa9T^Jk42oeyyyyeoltbM\n"+ + "NNbx|---------------^b8PPGa22y4ac^--^vLI46HHb885LvivivldRbH8bHO8HdbHdqmmppmGGG6GmDmpqwl^ -^^^^rrv31^^J52Gq2o9v-zU5kkPwZSZhstbM\n"+ + "NMpJ1---------------^k8ZkE24Uer- -^vAq8G6pH8R8ZzsJcivvvo6bDGHO8HqppHppmmpqGGGGGGmmmpqa^ - ^^Lr1|Sa4p8kC3oIxkSooAZk9E9jtbM\n"+ + "NMmJr----------------AOahmUJ^--r2m8RHkEqdH8888RRRRdFvvvS8oJkd6mHpqpdppmqdqG6G996GUGGmkr --- - -^---rxCAmHO69kayokHpXS54aSFtbM\n"+ + "NMqJr----------------jpqar-^tU80R88Aj9OpDOOO88888Rqt|7qHx|vvvsH8EEbHpGmqpqmGGG9G9GmU6E| ---- -- ---- ----^fSGmD9PkPZeCySmGP9mmutbM\n"+ + "NMpJr----------------jC^^lm00R88RpIVbbDHHdDOOHHbb88AoR9ttCAyY9RmFa8Od6mpppqmGGmmEmGk9GJ- -^^-- ^vr^--- -------^AqPEPP5eAa2eeyAmpGmutbM\n"+ + "NNHJr--------------r|^|U@0RRRRRNGc28HbHpqpObppHbbOEE8H9q888qpOOavIGp6eSqDpqqmmq6EmU9Eme^ ^^^^^--- -rttTvr^- ---^ap24ae4woyeeeeyykDputbM\n"+ + "NNOxr------------^|rtpR88888dqRPvA8dHDmmqODmmqdHpGq8pmbOObdH8bGI||vSz||smbpqppqk9P56E6Sr -^^^^^^^^^^^^----^^^^^^rrrvxI^- ---^A6j2ozyPPAyeeeeyy9OCtbM\n"+ + "NNOJr-----------|tFpWR8qEwA3sPP|zHpppmGpbqmmqpDqmHbmmqpDpp8RHmGu||yS||v|c4ddpHmP6ee5UEPt^r7xFYlvr|r^^^^^rrr|LYeaPE69aIvvT- ---^SkjyFsAwkU52eyeeuAbytbM\n"+ + "NNOJr---------^jA9pzrJ54aaozSP1lHpqpmGqqGGGGmpqmHq9U9mmGdmhppmpGntwjitIT||f42llkUnJt9EUPozovrl3CT^lGDqHOOpG5u7v|r|v|vsPa|-----^5Eoyt3wkkkUUk5ao3eqytbM\n"+ + "NNbJr---------FpEv---jk4Sa3AUvTdbppmmpq6G6Gmqqmq95wUGk6qx^2O9pq6UmP5mGGGa7||vvzdwVT|XGUmkyev-^e2elCje2r^--- ------^^-----^odUkfCPPkkkkkkUU4e6ytbM\n"+ + "NMptr^-------vqt----^Ak44eaGvJ88ppqmbp69E9GmqmqkSk6UGqPTrtmPmGEUUG596kkk9ksvvLaH4yv|A62CV2yeFLs2Jr^rYoz^ ---^^-----------------i8mO9FekUkkkkkkUPek3tbM\n"+ + "NMptr^-------h| ----^5XSAaELC88DppqHH6EEE9GmmqkPkZXGC^--^5mm8GUhUUw9kPPPPk9PAyUp5oj4asyX99E4v^^jIrrrtje|^^^^-------------------^GRGwaeyPkUkkkkkk25jtbM\n"+ + "NMpJr-------rJ------ikSA9UvaR8dpDpDbGEUUU9GGmqka56z^-- ^SSpOUGUGPPkPwZwwPU99Pm9PSUq4lCSXaoooCvjASS3Cui^^-----------------------tgPsooSo4EkPPPPP2astbM\n"+ + "NNHJr ------rr---- -oEw8e|UROHHdqHOGUUUUU96mmZ5wt^- rkaaPh4ZUXP5waa4ZPPkXPpwPwkEU5oCeAkPCXf^Jo2r--- ----------------------|H8SyzC5aeXkPPkkA2ItbM\n"+ + "NNbT^ -------^-----|kqGcjR0bppDH8OG9UkkkUU9Dm4AUCr^-----vUofa5ASka5a422A455w4PmAZXSZ555X9U7e4CPUeePe^^-------------^^^rr^^^^---^5HH8ajuCo5aaPkkk4yJtbM\n"+ + "NNbJr-------------^kHuFp0Rbpb8R88m69PU6GqmmHqGmpH8Oqkev^IPsTS425UASAA2y2Aaa4ePGoaZAaS4a4Sk1^4G4a5UqO888ROmmqG99mmpmGwyIv||v|r^^--^i6XuCyyya99PPkwCttbM\n"+ + "NNOxr------------^eosGRRR88RRR88H6GUkkkE9mpm6PAoSbOObEGHpwvLk2ePkAAoooye22A2eZZ3AA2a4aa4ASv-^9pqG6GpDdOg8qqmmqmb888ROXSH86wVLrrr^roZ33yyyee2S6q9kATtOM\n"+ + "NNbJr----------^ifyG8RRRRR88R888GGqkPPPPkGG6j^--vOma2aaA6mGUay2w4ooy3eyye2AoyFyCoAo2222SA2AztoDGH69mpd8ROppmmmmb8888mUc^e8dbRROPCCt7yeyeyeo22eSmpGltOM\n"+ + "NNOJr-rr^^^rrijakp88888888888bmqEqmkPPwPU9lse^ vpsrrCS|zqpOXjAYJ2oCCCCCye22C|j3e2yeeee5Aat--^COOpU6mqO8DpdmGmDOR88qa2AuIy5q8R8Hzi7lyeeyeeo22o4k6jvtOM\n"+ + "NNOxr--rJeX6mqH8ObOOO88888qPoja96bmPwXwPGX^^vi- ^ji^-^eAitZmPFCTrAAnjjuu3eeaI^teVoCyyyyooAz----n8O8pqmH8pppmmpb8888Vr^-^r|Js9WRRpCJuoeeeeo2222ADA-^tOM\n"+ + "NNOJr-----^^^zmGGmH88GkdPyzjeA66mbmPwXwkmU^ -^^--|F^-----^zL^r^--^vYeeyuny24|-|ay2VyyyeLL2o^ -^^SpqOHqdHqdpGmD8R88Ov- -^rr|TDW88Ujy2yyeeoAA2e5q| ^tOM\n"+ + "NNbtr------^l2yoyC4Gk6mAyaw5aa9GpHmPwhhkqp^ - --^^r^r^-rT^ - -^rLC4G2^ ^2nCCjyeAvr35|- --^kHpmmbppHmGpO88H85r^^^^r^^|l6g8ROAe2yeee24aeyGa^ rtOM\n"+ + "NNOlt|^-^|A4eA423jZ6h9kS6kSaA4GmDbpk55Pkm2r ----- ----^-- --r^--^oX4w4A24GGZ5Sv^-^^vRpdqmGDpmpH88qp8yr^^^v^^r|ud8888pS2eeeo2SaVypJ- rtOM\n"+ + "NNOxCGqEPaS969Z2njw9Pqp9UkwaeAqpHbH95Zw99Lr - - -L^ -rv|cXUZkhlzPPmpqqOP|^ebpH9mpmppO8mqpbui|r|fxLF4mq88888qAeeeoAh4uAk^ rtOM\n"+ + "NNOJjPSAoyPmXkGmGk99mm99kS2eem8pHHbmw55G9||- ^E2TxAlF4SS9qmGmwufGd9GqmqmO8GG9HEZ2L2qFvt44PGH8O888EeeooaP4u4A^ rtOM\n"+ + "NNOJF4SaSGm6XhPX45Gq66U55XSa6PqHpHHqPww9HPo^ ^Ir-^Je1|eP6x|oEEGUUEkmGmGp8E9EqqyC2PA5SavT5uoG8OOO8RGee24PSCZJ---rtOM\n"+ + "NMHJT|vP8Gk9PXP5XmqmmGGUkkEE7|68mpppUwkG|^rr ^^-----^uGi--^Ska2PhEGG6pHPPk68wVo2A5Gus1LeAXA4GDHO8RHAoZPSyw|---rtOM\n"+ + "NMDJ|LqHmGPEUhZkqpHqG99EEGAvTsCdqdpp6k9kr^^i^ -- --^^^^vvr--^teIvzkSP66Gpq55wkG6A22A4wquliteyye4wwXEqpO8Hkw42hr --rtOM\n"+ + "NNHJybqmm65k65Ppbpaa9E9EmoLVv^^PRqqmm9Ukr^^r|- ------ -^- --^^^^rt|^-^jwSU99mqk4ZZPU6P2aaaSwmYjJtyyyeeee2hGGqb88RbkXr---rtOM\n"+ + "NNbJ3qqm6E5aGwmO9ey5U99p2Lyr^^^v8OG6G6kkr^^^rr- - -- -^- - ----- -r45P99GmkAa44X55wS4S5SShEYaAlyyyyeeee2Zoe25E6m8qJr^-rtOM\n"+ + "NMpJCmmG9kXeXGq92yy4kkqkt2|^^^^^j8mE9U5bT^^^^r|- - ---- ^jwhEGGE5AAAAAha2Z24S45XwkZy2ya3yyyeeooAw2eoa55wGy- --rtOM\n"+ + "NMHJCmG9UPGyrkpaAyu259qLty^^^^^^^U8EEUwbGr^^^^rr^- --- --^rf59GGEka22AAAAwo3r|ooAa5XPEAwEt4eyyeeeeoAXAe245Zwp2- --rtOM\n"+ + "NNOxCG9kP9o^-1mG2ynyap4rTj^^^^^^^LbGkEP9qu^^^^^^^|^ -- -^|itzo5UUPeie5a4AAaAAaPufr-^3CeAS5wwam8eu4Cyeeee2aPSe2S5w5Go- --rtOM\n"+ + "NNOxuUkPmC^-^-|8q2YjaGF^vVr^^^^^^^zdEUX9kkt^^^^^^^r|- ------ --^|Iv^- ^PZZaAaAa5P3Ir -IyC2aZw4UG9EySCyeeeoA4Pwo2S5556S^ --rtOM\n"+ + "NNOJjXk9t^-^^--rGGaz2klrrAv^^^^^^^^2qEP6mP6f^^^^^^|ke^- ^r1^^^rr1ySS4AAASPUAzr- veu2A4SUpkZG45ACyeeoa4XPA2S555k9| rtOM\n"+ + "NNbJj9P|^-^^-- rmSaUUjrrJor^^^^^^^^SqUGkvv2Av^^^^YP|^r- -^|2i^^^^^^-chAa4A2wkU5ot^^-- |2C2A4kSy4UUZkhnyyeeaShk4ASwwwwG2- ^tOM\n"+ + "NNbJVe^^^^^- --- ^Xko5Syv^xyrr^^^^^^^up9qF^rr^^^^|aer^^r^- ---^|IJrvUF^^^^^^^vS4AaawE999w1- ---^Joy2Ame-^r3m4kPjC3yea5Xkw4S5w5h9mv- ^tOM\n"+ + "NNblv^^^^^--^--^^-^ekaS46Us4errr^^^^^^vkkkPCv||^^7hl^^^^^rr^----^^^r|v7xsCoaAIr^iGu^^^^^^^|aSAaPU9UEqe^ -C2e2U3- -L^jEmPzyeo2SwwUPSSw5w9S3kr ^tOM\n"+ + "NNOJvr^^^-rr-^^^----r5GkAwkUm4vrrr^^^^^ryPPj^^^ -i4i^^^^^^^rtYJs2SA2eyy3jt1^^-^fEy^^^^^^^v4SAZPkUUmmL- ^5o2Ua^ ^vtGqmwZSaSZ44ZXkPkkUO9rfa-^tOM\n"+ + "NNbtv^^^ r1^^^rr^----^yEPU9UX4PV|rr^^^^^-|zAki- -vAJ^^^^rr|JfT7i^^r^^^^^^^^^^^jUJ^^^^^^^Jk5ZhPhP9qC^ TE4kv-rr-^vAauYffFsssssuAASk6UE99E6RAitOM\n"+ + "NNOJv^^ -rr^^^^rCyvrr^^F6PXPkk2aAL|r^^^- ---rJv^-r2i^rrtIvr^^^rv^^^^^^^^^^^^rV2v^^^--^ckk5PkkPUmA^ ^EqP^ -fPsTxfFsszzzzjzjF7tlF2U6k6mqmbstOM\n"+ + "NNbJLr^rv|rrr^^uPS52Yv^-1PaA2eo2yzF|^- ----r2Trt7v^--- -^vv^^^^^^^^^|t2zr- --rCGU5kUUPkGPr- -eU|- -|oCsJIYYFssjzzjzjjYtlye22eSdOdpDstOM\n"+ + "NNbxi|vtu|rrrrv5hPkkytv|vV4e3eAejfeT- ^3jT||ir^-----^ir^^^^^--^I23oyuy4GGw5kEkPP5jr- --- -rv^ ^waFAAy442VujnnjsjyeyJv||LlYT|iyUbztOM\n"+ + "NQOJT|^|lrrrrrFEPUUolxteAya2sItloejv- -LeTr1vr^^^^^^|t^- -vSY^ -rLAUS4h542Ccr^-- ---- -- ^94CoZAye22AaAA2oAIrrriCFyXZkEAtJvr|tON\n"+ + "QQ8YtJLtTr^rrreGkEkjJtJ4S3Aw3TLvilyc- ^as|r|rrvrr1|Jl^ ^Ca|- -^Lyoe2ezcr^^^^- ------ ^Hk2ya5Z5S4w4oeey2Sr^JezTAaw9hSc^vzl7l8N\n"+ + "QQN08dZstL|rrr2Gk6kzt7sS2CA4Af|1||TL- -Torrvietrvir^- -vAIrrLzAaeCJ|r^^^^^^- ------ -ADSAVA2y2k5eCCCzFze|^TCESvr1rvlTT3PH80MQ\n"+ + "QQQQNNMRmVtTLvAmU6UjtcjAyuAAASu|rrv|- ^2z^^^^^^-- -rAI^ ------^--^^^-- ------ rDaSSS4ZU5yCy3jFFzsyirTCoXPoT||t2OgMNNQQQ\n"+ + "QQQQQQQNNRSxTvVdEGECJcsSojV4a5t^rrLr -LUr -r2u^- -----^^^^---- - ------ -om4S5SU62yooenszssf3t^|oneuTi7lUgMNNQQQQQ\n"+ + "QQQQQQQQNMgGlLT9qUG2x7JSS2zICSA^-Jx- ^eo^ -^yer- ------- - -- ---- ^Gk5kk9SFsnzuCCCe2225y^^jzPi^|J9gNNQQQQQQQ\n"+ + "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n"+ + "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; + + System.out.println(" _____________________________"+ + "_______________________________\n" + " Hey hey, I'm Sparkle!\n" + " _____________________________"+ + "_______________________________\n" + "\n" + logo); - System.out.println( - " _____________________________" - + "_______________________________\n" - + " Hey hey, I'm Sparkle!\n" - + " _____________________________" - + "_______________________________\n" - + "\n" - + logo); + System.out.println(" _____________________________"+ + "_______________________________\n" + + " Got any cool, daring quests or risky biz? Just hit me up!\n"+ + " _____________________________"+ + "_______________________________\n"); - System.out.println( - " _____________________________" - + "_______________________________\n" - + " Got any cool, daring quests or risky biz? Just hit me up!\n" - + " _____________________________" - + "_______________________________\n"); - - Task[] tasks = new Task[100]; - int taskCount = 0; - - String userInput = scanner.nextLine(); - while (!userInput.equalsIgnoreCase("bye")) { - if (userInput.equalsIgnoreCase("list")) { - System.out.println( - " _________________________________" + "___________________________\n"); - if (taskCount == 0) { - System.out.println(" Looks like there's nothing fun to mess with... How boring!"); - } else { - for (int i = 0; i < taskCount; i++) { - System.out.println( - " " - + (i + 1) - + ". [" - + tasks[i].getStatusIcon() - + "] " - + tasks[i].description - + "~♪"); - } - } - System.out.println( - " _________________________________" + "___________________________\n"); - } else if (userInput.startsWith("mark")) { - int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; - if (taskNumber >= 0 && taskNumber < taskCount) { - tasks[taskNumber].markAsDone(); - System.out.println( - " _____________________________" - + "_______________________________\n" - + " Boom! Task's done and dusted~\n" - + " [" - + tasks[taskNumber].getStatusIcon() - + "] " - + tasks[taskNumber].description - + "\n" - + " _____________________________" - + "_______________________________\n"); - } else { - System.out.println( - " _____________________________" - + "_______________________________\n" - + " That task number's playing hide and seek—try again!.\n" - + " _____________________________" - + "_______________________________\n"); + String userInput = scanner.nextLine(); + while(!userInput.equalsIgnoreCase("bye")){ + System.out.println(" _________________________________"+ + "___________________________\n"+ + " "+ + userInput+ "~" + + "\n"+ + " _________________________________"+ + "___________________________\n"); + userInput = scanner.nextLine(); } - } else if (userInput.startsWith("unmark")) { - int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; - if (taskNumber >= 0 && taskNumber < taskCount) { - tasks[taskNumber].markAsUndone(); - System.out.println( - " _____________________________" - + "_______________________________\n" - + " Oops! Not done yet, but it's still on the radar!\n" - + " [" - + tasks[taskNumber].getStatusIcon() - + "] " - + tasks[taskNumber].description - + "\n" - + " _____________________________" - + "_______________________________\n"); - } else { - System.out.println( - " _____________________________" - + "_______________________________\n" - + " That task number's playing hide and seek—try again!\n" - + " _____________________________" - + "_______________________________\n"); - } - } else { - // Add the task if it's not "list" - tasks[taskCount] = new Task(userInput); - taskCount++; - System.out.println( - " _____________________________" - + "_______________________________\n" - + " added: " - + userInput - + "! Let\'s make it fun~" - + "\n" - + " _____________________________" - + "_______________________________\n"); - } - userInput = scanner.nextLine(); + + System.out.println(" _________________________________"+ + "___________________________\n" + + " See you around, Stelle~ Try to stay out of trouble, especially... the next time we meet!\n" + + " _________________________________"+ + "___________________________\n"); + scanner.close(); } - - System.out.println( - " ____________________________________________________________\n" - + " See you around, Stelle~ Try to stay out of trouble, especially... the next time" - + " we meet!\n" - + " ____________________________________________________________\n"); - scanner.close(); - } -} +} \ No newline at end of file diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 3be2b901f..0e1d775a0 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -14,10 +14,4 @@ public String getStatusIcon() { public void markAsDone() { this.isDone = true; } - - public void markAsUndone() { - this.isDone = false; - } - - } \ No newline at end of file From f41bae3c9bddf361b0b55068aedd5c1b0348b510 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 04:00:36 +0800 Subject: [PATCH 08/43] Add markAsUndone method to Task class --- src/main/java/Task.java | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 0e1d775a0..1d00e5b75 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,17 +1,21 @@ public class Task { - protected String description; - protected boolean isDone; + protected String description; + protected boolean isDone; - public Task(String description) { - this.description = description; - this.isDone = false; - } + public Task(String description) { + this.description = description; + this.isDone = false; + } - public String getStatusIcon() { - return (isDone ? "X" : " "); // mark done task with X - } + public String getStatusIcon() { + return (isDone ? "X" : " "); // mark done task with X + } - public void markAsDone() { - this.isDone = true; - } -} \ No newline at end of file + public void markAsDone() { + this.isDone = true; + } + + public void markAsUndone() { + this.isDone = false; + } +} From 212b4c0dae8c8160fd4df4b2234784e7d0f51e24 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 04:01:33 +0800 Subject: [PATCH 09/43] Add the function to control tasks as list and mark/unmark them --- src/main/java/Sparkle.java | 362 ++++++++++++++++++++++++++----------- 1 file changed, 258 insertions(+), 104 deletions(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index 1e608101a..5ecbfc48f 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -1,112 +1,266 @@ import java.util.Scanner; public class Sparkle { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); - String logo = "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n"+ - "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n"+ - "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n"+ - "QQQQQQNMMgmJiLTTtttttttttttTJX5Aaa444AA22o2AwU4S6PPkP5Pr^SSr^^^^^^^^^^^^^^^^^^rJ^ --^vir^^^^^^rrr1|LtIuyeAOP2PUkZpBBBO954S5XPPkUE9666GGGUYtGgMMNQQQQQQ\n"+ - "QQQQNNMMR5TL7TTTttTTT7cLLivv|ia42222oo2oeooooeoSPPkPPm|-tdEer^^^^^^^^^^^^^^^^^ir---- ^r|v^^^^^rr|vLtFCe2AAHGeZPU5ARBBQqU4aS444SSSSSZ5wXPP5FcSRgMMNQQQQ\n"+ - "QQNMgRH4JiLLLLivvvv||1rrrrrr^^LE5eoooooeoooooooeo4PhPk^^ko49e^^^^^^^^^^^^^^^^rJ^-----^7Trrvr^^rrr|vvi7tIzs9be2XPkZAURBR6h22AAAAAAAAAAAaaa44ettApRgMNNQ\n"+ - "QQRAFTvvv|||rrrrrr^^^^^^^^^^rwevu95oeoeoeeeeeoooeeoaP4ioZooAkC^^^^^^^r|fASaoCAs------^yMHv^rvr^^^rrrrrr|||u8AVZXPEGGSOQqwaaAAAAAAA2AAA2AAAAAAostTI34RQ\n"+ - "NQ8J|rrrrr^^^^^^^^^^^^^^^^^eZLTeU88Hmk5SZZ5S4aAAAo2a24LF5oo2Pkr-^rtoSAyA69UU5wT---- -^2R0Q5r^||^^^^^^^^^^^rqEjAwXUGpUSRgh4A4SSSS4aAAAA22222o2222oeLLON\n"+ - "NNOJ|^^^^^^^^^^^^^^^^^^^^vZIf98O6kPk9b88mGUkkkVr^rFousttA2oePPlomOO88dGkU88HHpi- -reRRRNEr^^F5t|r^^^^^-^kHey5wSaGau8Bq3tvctJYzCyeo22o22222222o27cbN\n"+ - "NNOJ1^^^^^^^^^^^^^^^^^^^lyF6RbUUmpqG9kw5SSkkkC|3EkXS2ye4422PORRRRR888888OD88Hqv -ru88RRg9|^^rmmyXUzTvrrG82joSS3jzoRQR2i^rrrrr||viTJIzCVyeeeeeo7cbM\n"+ - "NNOJ1^^^^^^^^^^^^^^^^^reyP88mmDEa2AAAaZwPPEUXkqE5Pk99kkUU68RRR8888888OdDO8O88Ov -^xO888R@kr^^^2gR8R8Fe8OUaujyASSA6qjaPt^-^^^^^^rrrrrr|vLtlIj42LcbM\n"+ - "NNOJ1^^^^^^^^^^^^^^^^rXGH8Obmw22222Aa44ZXk6G9UUGmEZa46qO8R8888888ObO8888ObHHb8J- ^imR88R8f^^^--|mRR5vrv3PkaCje2SkHmYApPr------^^^^^^TA1rrrLUmJ|cbM\n"+ - "NNOJr^^^^^^^^^^^^^^^^XQ8bR8ko2A22oo2AAAAAA2Aw9G9E6mUPGO888bHbbHH888HHHHHHbHHHOe- ^|PR88R4r^^--^^rVv-^^^--^rYuzC24w9PnkOr^^^^-------TPSe^^jEm5|r7bM\n"+ - "NNOJr^^^^^^^^^^^^^^-|WWD8H42A2222o2AAAAAAAX66AC5myJw8R8888HHOHbbDdbObbOObHddpbP^ -rARO88x^^----^r^1v^- -^7jje45k998Gr^^^^^^^-^CZoy5ASGEm2^r7bM\n"+ - "NNOJr^^^^^^^^^^^^^^-JB0pw2AA2222222AAa4PUP2jf26srsORR8808bOObO88RRgggRR8888888O| ----rj888Oj^^^^-^^^^^- - -^tyyA5PUmpC^^^^^^vyZ2o4UmG96UGe^r7bM\n"+ - "NNOJ1^^^^^^^^^^^^^-^4RkA4ZZSSSSSZ5Zwkk5yIjCYyI^c8RRR88RR888ObbOO888OHddpppppH8Ra- ----^Lm8O8UJ^-----^|^ - -rTfoASXEmdy^^ru5SA5UGG9E9GESXx-^TOM\n"+ - "NNOJr^^^^^^^^^^-^rJwkShkkPPPPPPPkPPS2C3eF1rTrrGNRR8OR0OGPkGH88888OHDDdppqqqpppbHr ----^rS8bO8moLr^^rTr -^v22e45kGqksCw4PEPAP6969E52eUT-rTOM\n"+ - "NNOJr^^^^^^--^1f56kXkkPkPPPPPPwZ4SSA2jvr^|2^TWRRMgmoFs4m8RR88888HqmqpqppppppdHORa- ----^lHOdpqHy||x|- - -^ceLLyPPm9AAAAa2^^kG9hAee3Am3LctbM\n"+ - "NNOJr^^^^-^T4k9EUEEkGmmGqpHOq6UwaAoyJvv|vA|eMWWmIrvS8gR88888R8pmmmmmmqdODpqpppdbHL-----^rkOmdUr-rrrr- --^rr^-^e2PGaoG9py-TmX2yyyC2q8bettbM\n"+ - "NNOJr^^^^^----^^^^-^4QRbq6pqaoeeyyoVJTccEePMqs^^j8R88OO88888OpmGGGGp88OqmqDDppdHOpr ----^xPCo|-L|- ^^rLv^--rvfmGz4mkrrP4yyyVekq9EpRetbM\n"+ - "NNOJr^^^^-----------uBRD6UdU2oeeye23fxLA8Gz^-|908bHHObqq8888HqmGGHRR8Hmp88dpdpppb8u-----rr---^^|r- -^vu7r^^^^rnm25s^|96kha2Ak6kE6mb3tbM\n"+ - "NNDJ|^^^------------LQRpEGma2eeee2ACYj4ar-^C88OHbHO8PCER888OdmGHR8O8Hq88pmpDpqqqmdq|--^r-^vcvvr-------- -^-^--^--rIpPoiFUwoyy3yyy3Cy3y2ItbM\n"+ - "NMdJ1^--------------|MRGkmU22oeeoAA2Sl^-rkR8ObbHO8ktTUR8888Hqd88O88qD8dmqppqmmqmGqO9rr^^v7^- --^^^----- -^rr----^^repAzky||2233yyyyyyyyyxtbM\n"+ - "NNbJ|^--------------rRRUPmw2AeyyAU4|--vSEASmpHb8pnvvlm8888Op88OO8bpb8pmmppqmmmmGGqHH9|rYr- --io|^--^^--IO2ySa9T^Jk42oeyyyyeoltbM\n"+ - "NNbx|---------------^b8PPGa22y4ac^--^vLI46HHb885LvivivldRbH8bHO8HdbHdqmmppmGGG6GmDmpqwl^ -^^^^rrv31^^J52Gq2o9v-zU5kkPwZSZhstbM\n"+ - "NMpJ1---------------^k8ZkE24Uer- -^vAq8G6pH8R8ZzsJcivvvo6bDGHO8HqppHppmmpqGGGGGGmmmpqa^ - ^^Lr1|Sa4p8kC3oIxkSooAZk9E9jtbM\n"+ - "NMmJr----------------AOahmUJ^--r2m8RHkEqdH8888RRRRdFvvvS8oJkd6mHpqpdppmqdqG6G996GUGGmkr --- - -^---rxCAmHO69kayokHpXS54aSFtbM\n"+ - "NMqJr----------------jpqar-^tU80R88Aj9OpDOOO88888Rqt|7qHx|vvvsH8EEbHpGmqpqmGGG9G9GmU6E| ---- -- ---- ----^fSGmD9PkPZeCySmGP9mmutbM\n"+ - "NMpJr----------------jC^^lm00R88RpIVbbDHHdDOOHHbb88AoR9ttCAyY9RmFa8Od6mpppqmGGmmEmGk9GJ- -^^-- ^vr^--- -------^AqPEPP5eAa2eeyAmpGmutbM\n"+ - "NNHJr--------------r|^|U@0RRRRRNGc28HbHpqpObppHbbOEE8H9q888qpOOavIGp6eSqDpqqmmq6EmU9Eme^ ^^^^^--- -rttTvr^- ---^ap24ae4woyeeeeyykDputbM\n"+ - "NNOxr------------^|rtpR88888dqRPvA8dHDmmqODmmqdHpGq8pmbOObdH8bGI||vSz||smbpqppqk9P56E6Sr -^^^^^^^^^^^^----^^^^^^rrrvxI^- ---^A6j2ozyPPAyeeeeyy9OCtbM\n"+ - "NNOJr-----------|tFpWR8qEwA3sPP|zHpppmGpbqmmqpDqmHbmmqpDpp8RHmGu||yS||v|c4ddpHmP6ee5UEPt^r7xFYlvr|r^^^^^rrr|LYeaPE69aIvvT- ---^SkjyFsAwkU52eyeeuAbytbM\n"+ - "NNOJr---------^jA9pzrJ54aaozSP1lHpqpmGqqGGGGmpqmHq9U9mmGdmhppmpGntwjitIT||f42llkUnJt9EUPozovrl3CT^lGDqHOOpG5u7v|r|v|vsPa|-----^5Eoyt3wkkkUUk5ao3eqytbM\n"+ - "NNbJr---------FpEv---jk4Sa3AUvTdbppmmpq6G6Gmqqmq95wUGk6qx^2O9pq6UmP5mGGGa7||vvzdwVT|XGUmkyev-^e2elCje2r^--- ------^^-----^odUkfCPPkkkkkkUU4e6ytbM\n"+ - "NMptr^-------vqt----^Ak44eaGvJ88ppqmbp69E9GmqmqkSk6UGqPTrtmPmGEUUG596kkk9ksvvLaH4yv|A62CV2yeFLs2Jr^rYoz^ ---^^-----------------i8mO9FekUkkkkkkUPek3tbM\n"+ - "NMptr^-------h| ----^5XSAaELC88DppqHH6EEE9GmmqkPkZXGC^--^5mm8GUhUUw9kPPPPk9PAyUp5oj4asyX99E4v^^jIrrrtje|^^^^-------------------^GRGwaeyPkUkkkkkk25jtbM\n"+ - "NMpJr-------rJ------ikSA9UvaR8dpDpDbGEUUU9GGmqka56z^-- ^SSpOUGUGPPkPwZwwPU99Pm9PSUq4lCSXaoooCvjASS3Cui^^-----------------------tgPsooSo4EkPPPPP2astbM\n"+ - "NNHJr ------rr---- -oEw8e|UROHHdqHOGUUUUU96mmZ5wt^- rkaaPh4ZUXP5waa4ZPPkXPpwPwkEU5oCeAkPCXf^Jo2r--- ----------------------|H8SyzC5aeXkPPkkA2ItbM\n"+ - "NNbT^ -------^-----|kqGcjR0bppDH8OG9UkkkUU9Dm4AUCr^-----vUofa5ASka5a422A455w4PmAZXSZ555X9U7e4CPUeePe^^-------------^^^rr^^^^---^5HH8ajuCo5aaPkkk4yJtbM\n"+ - "NNbJr-------------^kHuFp0Rbpb8R88m69PU6GqmmHqGmpH8Oqkev^IPsTS425UASAA2y2Aaa4ePGoaZAaS4a4Sk1^4G4a5UqO888ROmmqG99mmpmGwyIv||v|r^^--^i6XuCyyya99PPkwCttbM\n"+ - "NNOxr------------^eosGRRR88RRR88H6GUkkkE9mpm6PAoSbOObEGHpwvLk2ePkAAoooye22A2eZZ3AA2a4aa4ASv-^9pqG6GpDdOg8qqmmqmb888ROXSH86wVLrrr^roZ33yyyee2S6q9kATtOM\n"+ - "NNbJr----------^ifyG8RRRRR88R888GGqkPPPPkGG6j^--vOma2aaA6mGUay2w4ooy3eyye2AoyFyCoAo2222SA2AztoDGH69mpd8ROppmmmmb8888mUc^e8dbRROPCCt7yeyeyeo22eSmpGltOM\n"+ - "NNOJr-rr^^^rrijakp88888888888bmqEqmkPPwPU9lse^ vpsrrCS|zqpOXjAYJ2oCCCCCye22C|j3e2yeeee5Aat--^COOpU6mqO8DpdmGmDOR88qa2AuIy5q8R8Hzi7lyeeyeeo22o4k6jvtOM\n"+ - "NNOxr--rJeX6mqH8ObOOO88888qPoja96bmPwXwPGX^^vi- ^ji^-^eAitZmPFCTrAAnjjuu3eeaI^teVoCyyyyooAz----n8O8pqmH8pppmmpb8888Vr^-^r|Js9WRRpCJuoeeeeo2222ADA-^tOM\n"+ - "NNOJr-----^^^zmGGmH88GkdPyzjeA66mbmPwXwkmU^ -^^--|F^-----^zL^r^--^vYeeyuny24|-|ay2VyyyeLL2o^ -^^SpqOHqdHqdpGmD8R88Ov- -^rr|TDW88Ujy2yyeeoAA2e5q| ^tOM\n"+ - "NNbtr------^l2yoyC4Gk6mAyaw5aa9GpHmPwhhkqp^ - --^^r^r^-rT^ - -^rLC4G2^ ^2nCCjyeAvr35|- --^kHpmmbppHmGpO88H85r^^^^r^^|l6g8ROAe2yeee24aeyGa^ rtOM\n"+ - "NNOlt|^-^|A4eA423jZ6h9kS6kSaA4GmDbpk55Pkm2r ----- ----^-- --r^--^oX4w4A24GGZ5Sv^-^^vRpdqmGDpmpH88qp8yr^^^v^^r|ud8888pS2eeeo2SaVypJ- rtOM\n"+ - "NNOxCGqEPaS969Z2njw9Pqp9UkwaeAqpHbH95Zw99Lr - - -L^ -rv|cXUZkhlzPPmpqqOP|^ebpH9mpmppO8mqpbui|r|fxLF4mq88888qAeeeoAh4uAk^ rtOM\n"+ - "NNOJjPSAoyPmXkGmGk99mm99kS2eem8pHHbmw55G9||- ^E2TxAlF4SS9qmGmwufGd9GqmqmO8GG9HEZ2L2qFvt44PGH8O888EeeooaP4u4A^ rtOM\n"+ - "NNOJF4SaSGm6XhPX45Gq66U55XSa6PqHpHHqPww9HPo^ ^Ir-^Je1|eP6x|oEEGUUEkmGmGp8E9EqqyC2PA5SavT5uoG8OOO8RGee24PSCZJ---rtOM\n"+ - "NMHJT|vP8Gk9PXP5XmqmmGGUkkEE7|68mpppUwkG|^rr ^^-----^uGi--^Ska2PhEGG6pHPPk68wVo2A5Gus1LeAXA4GDHO8RHAoZPSyw|---rtOM\n"+ - "NMDJ|LqHmGPEUhZkqpHqG99EEGAvTsCdqdpp6k9kr^^i^ -- --^^^^vvr--^teIvzkSP66Gpq55wkG6A22A4wquliteyye4wwXEqpO8Hkw42hr --rtOM\n"+ - "NNHJybqmm65k65Ppbpaa9E9EmoLVv^^PRqqmm9Ukr^^r|- ------ -^- --^^^^rt|^-^jwSU99mqk4ZZPU6P2aaaSwmYjJtyyyeeee2hGGqb88RbkXr---rtOM\n"+ - "NNbJ3qqm6E5aGwmO9ey5U99p2Lyr^^^v8OG6G6kkr^^^rr- - -- -^- - ----- -r45P99GmkAa44X55wS4S5SShEYaAlyyyyeeee2Zoe25E6m8qJr^-rtOM\n"+ - "NMpJCmmG9kXeXGq92yy4kkqkt2|^^^^^j8mE9U5bT^^^^r|- - ---- ^jwhEGGE5AAAAAha2Z24S45XwkZy2ya3yyyeeooAw2eoa55wGy- --rtOM\n"+ - "NMHJCmG9UPGyrkpaAyu259qLty^^^^^^^U8EEUwbGr^^^^rr^- --- --^rf59GGEka22AAAAwo3r|ooAa5XPEAwEt4eyyeeeeoAXAe245Zwp2- --rtOM\n"+ - "NNOxCG9kP9o^-1mG2ynyap4rTj^^^^^^^LbGkEP9qu^^^^^^^|^ -- -^|itzo5UUPeie5a4AAaAAaPufr-^3CeAS5wwam8eu4Cyeeee2aPSe2S5w5Go- --rtOM\n"+ - "NNOxuUkPmC^-^-|8q2YjaGF^vVr^^^^^^^zdEUX9kkt^^^^^^^r|- ------ --^|Iv^- ^PZZaAaAa5P3Ir -IyC2aZw4UG9EySCyeeeoA4Pwo2S5556S^ --rtOM\n"+ - "NNOJjXk9t^-^^--rGGaz2klrrAv^^^^^^^^2qEP6mP6f^^^^^^|ke^- ^r1^^^rr1ySS4AAASPUAzr- veu2A4SUpkZG45ACyeeoa4XPA2S555k9| rtOM\n"+ - "NNbJj9P|^-^^-- rmSaUUjrrJor^^^^^^^^SqUGkvv2Av^^^^YP|^r- -^|2i^^^^^^-chAa4A2wkU5ot^^-- |2C2A4kSy4UUZkhnyyeeaShk4ASwwwwG2- ^tOM\n"+ - "NNbJVe^^^^^- --- ^Xko5Syv^xyrr^^^^^^^up9qF^rr^^^^|aer^^r^- ---^|IJrvUF^^^^^^^vS4AaawE999w1- ---^Joy2Ame-^r3m4kPjC3yea5Xkw4S5w5h9mv- ^tOM\n"+ - "NNblv^^^^^--^--^^-^ekaS46Us4errr^^^^^^vkkkPCv||^^7hl^^^^^rr^----^^^r|v7xsCoaAIr^iGu^^^^^^^|aSAaPU9UEqe^ -C2e2U3- -L^jEmPzyeo2SwwUPSSw5w9S3kr ^tOM\n"+ - "NNOJvr^^^-rr-^^^----r5GkAwkUm4vrrr^^^^^ryPPj^^^ -i4i^^^^^^^rtYJs2SA2eyy3jt1^^-^fEy^^^^^^^v4SAZPkUUmmL- ^5o2Ua^ ^vtGqmwZSaSZ44ZXkPkkUO9rfa-^tOM\n"+ - "NNbtv^^^ r1^^^rr^----^yEPU9UX4PV|rr^^^^^-|zAki- -vAJ^^^^rr|JfT7i^^r^^^^^^^^^^^jUJ^^^^^^^Jk5ZhPhP9qC^ TE4kv-rr-^vAauYffFsssssuAASk6UE99E6RAitOM\n"+ - "NNOJv^^ -rr^^^^rCyvrr^^F6PXPkk2aAL|r^^^- ---rJv^-r2i^rrtIvr^^^rv^^^^^^^^^^^^rV2v^^^--^ckk5PkkPUmA^ ^EqP^ -fPsTxfFsszzzzjzjF7tlF2U6k6mqmbstOM\n"+ - "NNbJLr^rv|rrr^^uPS52Yv^-1PaA2eo2yzF|^- ----r2Trt7v^--- -^vv^^^^^^^^^|t2zr- --rCGU5kUUPkGPr- -eU|- -|oCsJIYYFssjzzjzjjYtlye22eSdOdpDstOM\n"+ - "NNbxi|vtu|rrrrv5hPkkytv|vV4e3eAejfeT- ^3jT||ir^-----^ir^^^^^--^I23oyuy4GGw5kEkPP5jr- --- -rv^ ^waFAAy442VujnnjsjyeyJv||LlYT|iyUbztOM\n"+ - "NQOJT|^|lrrrrrFEPUUolxteAya2sItloejv- -LeTr1vr^^^^^^|t^- -vSY^ -rLAUS4h542Ccr^-- ---- -- ^94CoZAye22AaAA2oAIrrriCFyXZkEAtJvr|tON\n"+ - "QQ8YtJLtTr^rrreGkEkjJtJ4S3Aw3TLvilyc- ^as|r|rrvrr1|Jl^ ^Ca|- -^Lyoe2ezcr^^^^- ------ ^Hk2ya5Z5S4w4oeey2Sr^JezTAaw9hSc^vzl7l8N\n"+ - "QQN08dZstL|rrr2Gk6kzt7sS2CA4Af|1||TL- -Torrvietrvir^- -vAIrrLzAaeCJ|r^^^^^^- ------ -ADSAVA2y2k5eCCCzFze|^TCESvr1rvlTT3PH80MQ\n"+ - "QQQQNNMRmVtTLvAmU6UjtcjAyuAAASu|rrv|- ^2z^^^^^^-- -rAI^ ------^--^^^-- ------ rDaSSS4ZU5yCy3jFFzsyirTCoXPoT||t2OgMNNQQQ\n"+ - "QQQQQQQNNRSxTvVdEGECJcsSojV4a5t^rrLr -LUr -r2u^- -----^^^^---- - ------ -om4S5SU62yooenszssf3t^|oneuTi7lUgMNNQQQQQ\n"+ - "QQQQQQQQNMgGlLT9qUG2x7JSS2zICSA^-Jx- ^eo^ -^yer- ------- - -- ---- ^Gk5kk9SFsnzuCCCe2225y^^jzPi^|J9gNNQQQQQQQ\n"+ - "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n"+ - "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; - - System.out.println(" _____________________________"+ - "_______________________________\n" + " Hey hey, I'm Sparkle!\n" + " _____________________________"+ - "_______________________________\n" + "\n" + logo); + String logo = + "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n" + + "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n" + + "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n" + + "QQQQQQNMMgmJiLTTtttttttttttTJX5Aaa444AA22o2AwU4S6PPkP5Pr^SSr^^^^^^^^^^^^^^^^^^rJ^" + + " --^vir^^^^^^rrr1|LtIuyeAOP2PUkZpBBBO954S5XPPkUE9666GGGUYtGgMMNQQQQQQ\n" + + "QQQQNNMMR5TL7TTTttTTT7cLLivv|ia42222oo2oeooooeoSPPkPPm|-tdEer^^^^^^^^^^^^^^^^^ir----" + + " ^r|v^^^^^rr|vLtFCe2AAHGeZPU5ARBBQqU4aS444SSSSSZ5wXPP5FcSRgMMNQQQQ\n" + + "QQNMgRH4JiLLLLivvvv||1rrrrrr^^LE5eoooooeoooooooeo4PhPk^^ko49e^^^^^^^^^^^^^^^^rJ^-----^7Trrvr^^rrr|vvi7tIzs9be2XPkZAURBR6h22AAAAAAAAAAAaaa44ettApRgMNNQ\n" + + "QQRAFTvvv|||rrrrrr^^^^^^^^^^rwevu95oeoeoeeeeeoooeeoaP4ioZooAkC^^^^^^^r|fASaoCAs------^yMHv^rvr^^^rrrrrr|||u8AVZXPEGGSOQqwaaAAAAAAA2AAA2AAAAAAostTI34RQ\n" + + "NQ8J|rrrrr^^^^^^^^^^^^^^^^^eZLTeU88Hmk5SZZ5S4aAAAo2a24LF5oo2Pkr-^rtoSAyA69UU5wT----" + + " -^2R0Q5r^||^^^^^^^^^^^rqEjAwXUGpUSRgh4A4SSSS4aAAAA22222o2222oeLLON\n" + + "NNOJ|^^^^^^^^^^^^^^^^^^^^vZIf98O6kPk9b88mGUkkkVr^rFousttA2oePPlomOO88dGkU88HHpi- " + + " -reRRRNEr^^F5t|r^^^^^-^kHey5wSaGau8Bq3tvctJYzCyeo22o22222222o27cbN\n" + + "NNOJ1^^^^^^^^^^^^^^^^^^^lyF6RbUUmpqG9kw5SSkkkC|3EkXS2ye4422PORRRRR888888OD88Hqv " + + " -ru88RRg9|^^rmmyXUzTvrrG82joSS3jzoRQR2i^rrrrr||viTJIzCVyeeeeeo7cbM\n" + + "NNOJ1^^^^^^^^^^^^^^^^^reyP88mmDEa2AAAaZwPPEUXkqE5Pk99kkUU68RRR8888888OdDO8O88Ov " + + " -^xO888R@kr^^^2gR8R8Fe8OUaujyASSA6qjaPt^-^^^^^^rrrrrr|vLtlIj42LcbM\n" + + "NNOJ1^^^^^^^^^^^^^^^^rXGH8Obmw22222Aa44ZXk6G9UUGmEZa46qO8R8888888ObO8888ObHHb8J- " + + " ^imR88R8f^^^--|mRR5vrv3PkaCje2SkHmYApPr------^^^^^^TA1rrrLUmJ|cbM\n" + + "NNOJr^^^^^^^^^^^^^^^^XQ8bR8ko2A22oo2AAAAAA2Aw9G9E6mUPGO888bHbbHH888HHHHHHbHHHOe- " + + " ^|PR88R4r^^--^^rVv-^^^--^rYuzC24w9PnkOr^^^^-------TPSe^^jEm5|r7bM\n" + + "NNOJr^^^^^^^^^^^^^^-|WWD8H42A2222o2AAAAAAAX66AC5myJw8R8888HHOHbbDdbObbOObHddpbP^ " + + " -rARO88x^^----^r^1v^- -^7jje45k998Gr^^^^^^^-^CZoy5ASGEm2^r7bM\n" + + "NNOJr^^^^^^^^^^^^^^-JB0pw2AA2222222AAa4PUP2jf26srsORR8808bOObO88RRgggRR8888888O| " + + " ----rj888Oj^^^^-^^^^^- - -^tyyA5PUmpC^^^^^^vyZ2o4UmG96UGe^r7bM\n" + + "NNOJ1^^^^^^^^^^^^^-^4RkA4ZZSSSSSZ5Zwkk5yIjCYyI^c8RRR88RR888ObbOO888OHddpppppH8Ra-" + + " ----^Lm8O8UJ^-----^|^ - -rTfoASXEmdy^^ru5SA5UGG9E9GESXx-^TOM\n" + + "NNOJr^^^^^^^^^^-^rJwkShkkPPPPPPPkPPS2C3eF1rTrrGNRR8OR0OGPkGH88888OHDDdppqqqpppbHr" + + " ----^rS8bO8moLr^^rTr -^v22e45kGqksCw4PEPAP6969E52eUT-rTOM\n" + + "NNOJr^^^^^^--^1f56kXkkPkPPPPPPwZ4SSA2jvr^|2^TWRRMgmoFs4m8RR88888HqmqpqppppppdHORa-" + + " ----^lHOdpqHy||x|- - -^ceLLyPPm9AAAAa2^^kG9hAee3Am3LctbM\n" + + "NNOJr^^^^-^T4k9EUEEkGmmGqpHOq6UwaAoyJvv|vA|eMWWmIrvS8gR88888R8pmmmmmmqdODpqpppdbHL-----^rkOmdUr-rrrr-" + + " --^rr^-^e2PGaoG9py-TmX2yyyC2q8bettbM\n" + + "NNOJr^^^^^----^^^^-^4QRbq6pqaoeeyyoVJTccEePMqs^^j8R88OO88888OpmGGGGp88OqmqDDppdHOpr" + + " ----^xPCo|-L|- ^^rLv^--rvfmGz4mkrrP4yyyVekq9EpRetbM\n" + + "NNOJr^^^^-----------uBRD6UdU2oeeye23fxLA8Gz^-|908bHHObqq8888HqmGGHRR8Hmp88dpdpppb8u-----rr---^^|r-" + + " -^vu7r^^^^rnm25s^|96kha2Ak6kE6mb3tbM\n" + + "NNDJ|^^^------------LQRpEGma2eeee2ACYj4ar-^C88OHbHO8PCER888OdmGHR8O8Hq88pmpDpqqqmdq|--^r-^vcvvr--------" + + " -^-^--^--rIpPoiFUwoyy3yyy3Cy3y2ItbM\n" + + "NMdJ1^--------------|MRGkmU22oeeoAA2Sl^-rkR8ObbHO8ktTUR8888Hqd88O88qD8dmqppqmmqmGqO9rr^^v7^-" + + " --^^^----- -^rr----^^repAzky||2233yyyyyyyyyxtbM\n" + + "NNbJ|^--------------rRRUPmw2AeyyAU4|--vSEASmpHb8pnvvlm8888Op88OO8bpb8pmmppqmmmmGGqHH9|rYr-" + + " --io|^--^^--IO2ySa9T^Jk42oeyyyyeoltbM\n" + + "NNbx|---------------^b8PPGa22y4ac^--^vLI46HHb885LvivivldRbH8bHO8HdbHdqmmppmGGG6GmDmpqwl^" + + " -^^^^rrv31^^J52Gq2o9v-zU5kkPwZSZhstbM\n" + + "NMpJ1---------------^k8ZkE24Uer-" + + " -^vAq8G6pH8R8ZzsJcivvvo6bDGHO8HqppHppmmpqGGGGGGmmmpqa^ - " + + " ^^Lr1|Sa4p8kC3oIxkSooAZk9E9jtbM\n" + + "NMmJr----------------AOahmUJ^--r2m8RHkEqdH8888RRRRdFvvvS8oJkd6mHpqpdppmqdqG6G996GUGGmkr" + + " --- - -^---rxCAmHO69kayokHpXS54aSFtbM\n" + + "NMqJr----------------jpqar-^tU80R88Aj9OpDOOO88888Rqt|7qHx|vvvsH8EEbHpGmqpqmGGG9G9GmU6E|" + + " ---- -- ---- ----^fSGmD9PkPZeCySmGP9mmutbM\n" + + "NMpJr----------------jC^^lm00R88RpIVbbDHHdDOOHHbb88AoR9ttCAyY9RmFa8Od6mpppqmGGmmEmGk9GJ-" + + " -^^-- ^vr^--- -------^AqPEPP5eAa2eeyAmpGmutbM\n" + + "NNHJr--------------r|^|U@0RRRRRNGc28HbHpqpObppHbbOEE8H9q888qpOOavIGp6eSqDpqqmmq6EmU9Eme^" + + " ^^^^^--- -rttTvr^- ---^ap24ae4woyeeeeyykDputbM\n" + + "NNOxr------------^|rtpR88888dqRPvA8dHDmmqODmmqdHpGq8pmbOObdH8bGI||vSz||smbpqppqk9P56E6Sr" + + " -^^^^^^^^^^^^----^^^^^^rrrvxI^- ---^A6j2ozyPPAyeeeeyy9OCtbM\n" + + "NNOJr-----------|tFpWR8qEwA3sPP|zHpppmGpbqmmqpDqmHbmmqpDpp8RHmGu||yS||v|c4ddpHmP6ee5UEPt^r7xFYlvr|r^^^^^rrr|LYeaPE69aIvvT-" + + " ---^SkjyFsAwkU52eyeeuAbytbM\n" + + "NNOJr---------^jA9pzrJ54aaozSP1lHpqpmGqqGGGGmpqmHq9U9mmGdmhppmpGntwjitIT||f42llkUnJt9EUPozovrl3CT^lGDqHOOpG5u7v|r|v|vsPa|-----^5Eoyt3wkkkUUk5ao3eqytbM\n" + + "NNbJr---------FpEv---jk4Sa3AUvTdbppmmpq6G6Gmqqmq95wUGk6qx^2O9pq6UmP5mGGGa7||vvzdwVT|XGUmkyev-^e2elCje2r^---" + + " ------^^-----^odUkfCPPkkkkkkUU4e6ytbM\n" + + "NMptr^-------vqt----^Ak44eaGvJ88ppqmbp69E9GmqmqkSk6UGqPTrtmPmGEUUG596kkk9ksvvLaH4yv|A62CV2yeFLs2Jr^rYoz^" + + " ---^^-----------------i8mO9FekUkkkkkkUPek3tbM\n" + + "NMptr^-------h|" + + " ----^5XSAaELC88DppqHH6EEE9GmmqkPkZXGC^--^5mm8GUhUUw9kPPPPk9PAyUp5oj4asyX99E4v^^jIrrrtje|^^^^-------------------^GRGwaeyPkUkkkkkk25jtbM\n" + + "NMpJr-------rJ------ikSA9UvaR8dpDpDbGEUUU9GGmqka56z^-- " + + " ^SSpOUGUGPPkPwZwwPU99Pm9PSUq4lCSXaoooCvjASS3Cui^^-----------------------tgPsooSo4EkPPPPP2astbM\n" + + "NNHJr ------rr---- -oEw8e|UROHHdqHOGUUUUU96mmZ5wt^- " + + " rkaaPh4ZUXP5waa4ZPPkXPpwPwkEU5oCeAkPCXf^Jo2r--- " + + " ----------------------|H8SyzC5aeXkPPkkA2ItbM\n" + + "NNbT^" + + " -------^-----|kqGcjR0bppDH8OG9UkkkUU9Dm4AUCr^-----vUofa5ASka5a422A455w4PmAZXSZ555X9U7e4CPUeePe^^-------------^^^rr^^^^---^5HH8ajuCo5aaPkkk4yJtbM\n" + + "NNbJr-------------^kHuFp0Rbpb8R88m69PU6GqmmHqGmpH8Oqkev^IPsTS425UASAA2y2Aaa4ePGoaZAaS4a4Sk1^4G4a5UqO888ROmmqG99mmpmGwyIv||v|r^^--^i6XuCyyya99PPkwCttbM\n" + + "NNOxr------------^eosGRRR88RRR88H6GUkkkE9mpm6PAoSbOObEGHpwvLk2ePkAAoooye22A2eZZ3AA2a4aa4ASv-^9pqG6GpDdOg8qqmmqmb888ROXSH86wVLrrr^roZ33yyyee2S6q9kATtOM\n" + + "NNbJr----------^ifyG8RRRRR88R888GGqkPPPPkGG6j^--vOma2aaA6mGUay2w4ooy3eyye2AoyFyCoAo2222SA2AztoDGH69mpd8ROppmmmmb8888mUc^e8dbRROPCCt7yeyeyeo22eSmpGltOM\n" + + "NNOJr-rr^^^rrijakp88888888888bmqEqmkPPwPU9lse^ " + + " vpsrrCS|zqpOXjAYJ2oCCCCCye22C|j3e2yeeee5Aat--^COOpU6mqO8DpdmGmDOR88qa2AuIy5q8R8Hzi7lyeeyeeo22o4k6jvtOM\n" + + "NNOxr--rJeX6mqH8ObOOO88888qPoja96bmPwXwPGX^^vi-" + + " ^ji^-^eAitZmPFCTrAAnjjuu3eeaI^teVoCyyyyooAz----n8O8pqmH8pppmmpb8888Vr^-^r|Js9WRRpCJuoeeeeo2222ADA-^tOM\n" + + "NNOJr-----^^^zmGGmH88GkdPyzjeA66mbmPwXwkmU^" + + " -^^--|F^-----^zL^r^--^vYeeyuny24|-|ay2VyyyeLL2o^ -^^SpqOHqdHqdpGmD8R88Ov- " + + " -^rr|TDW88Ujy2yyeeoAA2e5q| ^tOM\n" + + "NNbtr------^l2yoyC4Gk6mAyaw5aa9GpHmPwhhkqp^ - --^^r^r^-rT^ - -^rLC4G2^" + + " ^2nCCjyeAvr35|- --^kHpmmbppHmGpO88H85r^^^^r^^|l6g8ROAe2yeee24aeyGa^ rtOM\n" + + "NNOlt|^-^|A4eA423jZ6h9kS6kSaA4GmDbpk55Pkm2r ----- ----^-- " + + " --r^--^oX4w4A24GGZ5Sv^-^^vRpdqmGDpmpH88qp8yr^^^v^^r|ud8888pS2eeeo2SaVypJ- rtOM\n" + + "NNOxCGqEPaS969Z2njw9Pqp9UkwaeAqpHbH95Zw99Lr - - -L^ " + + " -rv|cXUZkhlzPPmpqqOP|^ebpH9mpmppO8mqpbui|r|fxLF4mq88888qAeeeoAh4uAk^ rtOM\n" + + "NNOJjPSAoyPmXkGmGk99mm99kS2eem8pHHbmw55G9||- " + + " ^E2TxAlF4SS9qmGmwufGd9GqmqmO8GG9HEZ2L2qFvt44PGH8O888EeeooaP4u4A^ rtOM\n" + + "NNOJF4SaSGm6XhPX45Gq66U55XSa6PqHpHHqPww9HPo^ " + + " ^Ir-^Je1|eP6x|oEEGUUEkmGmGp8E9EqqyC2PA5SavT5uoG8OOO8RGee24PSCZJ---rtOM\n" + + "NMHJT|vP8Gk9PXP5XmqmmGGUkkEE7|68mpppUwkG|^rr " + + " ^^-----^uGi--^Ska2PhEGG6pHPPk68wVo2A5Gus1LeAXA4GDHO8RHAoZPSyw|---rtOM\n" + + "NMDJ|LqHmGPEUhZkqpHqG99EEGAvTsCdqdpp6k9kr^^i^ -- " + + " --^^^^vvr--^teIvzkSP66Gpq55wkG6A22A4wquliteyye4wwXEqpO8Hkw42hr --rtOM\n" + + "NNHJybqmm65k65Ppbpaa9E9EmoLVv^^PRqqmm9Ukr^^r|- ------ -^-" + + " --^^^^rt|^-^jwSU99mqk4ZZPU6P2aaaSwmYjJtyyyeeee2hGGqb88RbkXr---rtOM\n" + + "NNbJ3qqm6E5aGwmO9ey5U99p2Lyr^^^v8OG6G6kkr^^^rr- - -- -^- " + + " - ----- -r45P99GmkAa44X55wS4S5SShEYaAlyyyyeeee2Zoe25E6m8qJr^-rtOM\n" + + "NMpJCmmG9kXeXGq92yy4kkqkt2|^^^^^j8mE9U5bT^^^^r|- - " + + " ---- ^jwhEGGE5AAAAAha2Z24S45XwkZy2ya3yyyeeooAw2eoa55wGy- --rtOM\n" + + "NMHJCmG9UPGyrkpaAyu259qLty^^^^^^^U8EEUwbGr^^^^rr^- --- " + + " --^rf59GGEka22AAAAwo3r|ooAa5XPEAwEt4eyyeeeeoAXAe245Zwp2- --rtOM\n" + + "NNOxCG9kP9o^-1mG2ynyap4rTj^^^^^^^LbGkEP9qu^^^^^^^|^ -- " + + " -^|itzo5UUPeie5a4AAaAAaPufr-^3CeAS5wwam8eu4Cyeeee2aPSe2S5w5Go- --rtOM\n" + + "NNOxuUkPmC^-^-|8q2YjaGF^vVr^^^^^^^zdEUX9kkt^^^^^^^r|- ------ " + + " --^|Iv^- ^PZZaAaAa5P3Ir -IyC2aZw4UG9EySCyeeeoA4Pwo2S5556S^ --rtOM\n" + + "NNOJjXk9t^-^^--rGGaz2klrrAv^^^^^^^^2qEP6mP6f^^^^^^|ke^- " + + " ^r1^^^rr1ySS4AAASPUAzr- veu2A4SUpkZG45ACyeeoa4XPA2S555k9| rtOM\n" + + "NNbJj9P|^-^^-- rmSaUUjrrJor^^^^^^^^SqUGkvv2Av^^^^YP|^r- " + + " -^|2i^^^^^^-chAa4A2wkU5ot^^-- |2C2A4kSy4UUZkhnyyeeaShk4ASwwwwG2- ^tOM\n" + + "NNbJVe^^^^^- --- ^Xko5Syv^xyrr^^^^^^^up9qF^rr^^^^|aer^^r^- " + + " ---^|IJrvUF^^^^^^^vS4AaawE999w1- ---^Joy2Ame-^r3m4kPjC3yea5Xkw4S5w5h9mv- ^tOM\n" + + "NNblv^^^^^--^--^^-^ekaS46Us4errr^^^^^^vkkkPCv||^^7hl^^^^^rr^----^^^r|v7xsCoaAIr^iGu^^^^^^^|aSAaPU9UEqe^" + + " -C2e2U3- -L^jEmPzyeo2SwwUPSSw5w9S3kr ^tOM\n" + + "NNOJvr^^^-rr-^^^----r5GkAwkUm4vrrr^^^^^ryPPj^^^" + + " -i4i^^^^^^^rtYJs2SA2eyy3jt1^^-^fEy^^^^^^^v4SAZPkUUmmL- ^5o2Ua^ " + + " ^vtGqmwZSaSZ44ZXkPkkUO9rfa-^tOM\n" + + "NNbtv^^^ r1^^^rr^----^yEPU9UX4PV|rr^^^^^-|zAki-" + + " -vAJ^^^^rr|JfT7i^^r^^^^^^^^^^^jUJ^^^^^^^Jk5ZhPhP9qC^ " + + " TE4kv-rr-^vAauYffFsssssuAASk6UE99E6RAitOM\n" + + "NNOJv^^ -rr^^^^rCyvrr^^F6PXPkk2aAL|r^^^-" + + " ---rJv^-r2i^rrtIvr^^^rv^^^^^^^^^^^^rV2v^^^--^ckk5PkkPUmA^ ^EqP^ " + + " -fPsTxfFsszzzzjzjF7tlF2U6k6mqmbstOM\n" + + "NNbJLr^rv|rrr^^uPS52Yv^-1PaA2eo2yzF|^- ----r2Trt7v^--- -^vv^^^^^^^^^|t2zr-" + + " --rCGU5kUUPkGPr- -eU|- -|oCsJIYYFssjzzjzjjYtlye22eSdOdpDstOM\n" + + "NNbxi|vtu|rrrrv5hPkkytv|vV4e3eAejfeT- " + + " ^3jT||ir^-----^ir^^^^^--^I23oyuy4GGw5kEkPP5jr- --- -rv^ " + + " ^waFAAy442VujnnjsjyeyJv||LlYT|iyUbztOM\n" + + "NQOJT|^|lrrrrrFEPUUolxteAya2sItloejv- -LeTr1vr^^^^^^|t^- -vSY^" + + " -rLAUS4h542Ccr^-- ---- -- ^94CoZAye22AaAA2oAIrrriCFyXZkEAtJvr|tON\n" + + "QQ8YtJLtTr^rrreGkEkjJtJ4S3Aw3TLvilyc- ^as|r|rrvrr1|Jl^ ^Ca|-" + + " -^Lyoe2ezcr^^^^- ------ ^Hk2ya5Z5S4w4oeey2Sr^JezTAaw9hSc^vzl7l8N\n" + + "QQN08dZstL|rrr2Gk6kzt7sS2CA4Af|1||TL- -Torrvietrvir^- " + + " -vAIrrLzAaeCJ|r^^^^^^- ------ " + + " -ADSAVA2y2k5eCCCzFze|^TCESvr1rvlTT3PH80MQ\n" + + "QQQQNNMRmVtTLvAmU6UjtcjAyuAAASu|rrv|- ^2z^^^^^^-- -rAI^ " + + " ------^--^^^-- ------ rDaSSS4ZU5yCy3jFFzsyirTCoXPoT||t2OgMNNQQQ\n" + + "QQQQQQQNNRSxTvVdEGECJcsSojV4a5t^rrLr -LUr -r2u^- -----^^^^----" + + " - ------ -om4S5SU62yooenszssf3t^|oneuTi7lUgMNNQQQQQ\n" + + "QQQQQQQQNMgGlLT9qUG2x7JSS2zICSA^-Jx- ^eo^ -^yer- ------- " + + " - -- ---- ^Gk5kk9SFsnzuCCCe2225y^^jzPi^|J9gNNQQQQQQQ\n" + + "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n" + + "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; - System.out.println(" _____________________________"+ - "_______________________________\n" + - " Got any cool, daring quests or risky biz? Just hit me up!\n"+ - " _____________________________"+ - "_______________________________\n"); + System.out.println( + " _____________________________" + + "_______________________________\n" + + " Hey hey, I'm Sparkle!\n" + + " _____________________________" + + "_______________________________\n" + + "\n" + + logo); - String userInput = scanner.nextLine(); - while(!userInput.equalsIgnoreCase("bye")){ - System.out.println(" _________________________________"+ - "___________________________\n"+ - " "+ - userInput+ "~" + - "\n"+ - " _________________________________"+ - "___________________________\n"); - userInput = scanner.nextLine(); + System.out.println( + " _____________________________" + + "_______________________________\n" + + " Got any cool, daring quests or risky biz? Just hit me up!\n" + + " _____________________________" + + "_______________________________\n"); + + Task[] tasks = new Task[100]; + int taskCount = 0; + + String userInput = scanner.nextLine(); + while (!userInput.equalsIgnoreCase("bye")) { + if (userInput.equalsIgnoreCase("list")) { + System.out.println( + " _________________________________" + "___________________________\n"); + if (taskCount == 0) { + System.out.println(" Looks like there's nothing fun to mess with... How boring!"); + } else { + for (int i = 0; i < taskCount; i++) { + System.out.println( + " " + + (i + 1) + + ". [" + + tasks[i].getStatusIcon() + + "] " + + tasks[i].description + + "~♪"); + } + } + System.out.println( + " _________________________________" + "___________________________\n"); + } else if (userInput.startsWith("mark")) { + int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; + if (taskNumber >= 0 && taskNumber < taskCount) { + tasks[taskNumber].markAsDone(); + System.out.println( + " _____________________________" + + "_______________________________\n" + + " Boom! Task's done and dusted~\n" + + " [" + + tasks[taskNumber].getStatusIcon() + + "] " + + tasks[taskNumber].description + + "\n" + + " _____________________________" + + "_______________________________\n"); + } else { + System.out.println( + " _____________________________" + + "_______________________________\n" + + " That task number's playing hide and seek—try again!.\n" + + " _____________________________" + + "_______________________________\n"); } - - System.out.println(" _________________________________"+ - "___________________________\n" + - " See you around, Stelle~ Try to stay out of trouble, especially... the next time we meet!\n" + - " _________________________________"+ - "___________________________\n"); - scanner.close(); + } else if (userInput.startsWith("unmark")) { + int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; + if (taskNumber >= 0 && taskNumber < taskCount) { + tasks[taskNumber].markAsUndone(); + System.out.println( + " _____________________________" + + "_______________________________\n" + + " Oops! Not done yet, but it's still on the radar!\n" + + " [" + + tasks[taskNumber].getStatusIcon() + + "] " + + tasks[taskNumber].description + + "\n" + + " _____________________________" + + "_______________________________\n"); + } else { + System.out.println( + " _____________________________" + + "_______________________________\n" + + " That task number's playing hide and seek—try again!\n" + + " _____________________________" + + "_______________________________\n"); + } + } else { + // Add the task if it's not "list" + tasks[taskCount] = new Task(userInput); + taskCount++; + System.out.println( + " _____________________________" + + "_______________________________\n" + + " added: " + + userInput + + "! Let\'s make it fun~" + + "\n" + + " _____________________________" + + "_______________________________\n"); + } + userInput = scanner.nextLine(); } -} \ No newline at end of file + + System.out.println( + " ____________________________________________________________\n" + + " See you around, Stelle~ Try to stay out of trouble, especially... the next time" + + " we meet!\n" + + " ____________________________________________________________\n"); + scanner.close(); + } +} From 4da7da5c48b12d67cf7095f8806d235ece54bd4e Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 05:26:13 +0800 Subject: [PATCH 10/43] Add styling file to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 2873e189e..e8cc99b2f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ bin/ /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT + +.vscode/ From 6ab6da20e2629dea520fc489504fe3f73e3f320d Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 05:27:38 +0800 Subject: [PATCH 11/43] Create two subclass of Task --- src/main/java/Deadline.java | 13 +++++++++++++ src/main/java/Todo.java | 10 ++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/main/java/Deadline.java create mode 100644 src/main/java/Todo.java diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 000000000..aabb0f016 --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,13 @@ +public class Deadline extends Task { + protected String by; + + public Deadline(String description, String by) { + super(description); + this.by = by; + } + + @Override + public String toString() { + return "[D]" + super.toString() + " (by: " + by + ")"; + } +} diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java new file mode 100644 index 000000000..4db97d719 --- /dev/null +++ b/src/main/java/Todo.java @@ -0,0 +1,10 @@ +public class Todo extends Task { + public Todo(String description) { + super(description); + } + + @Override + public String toString() { + return "[T]" + super.toString(); + } +} From c86d7db105fe7c21c14d31d33be8dbeb61a8f0d6 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 05:32:55 +0800 Subject: [PATCH 12/43] Create Event class that extends Task --- src/main/java/Event.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/Event.java diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 000000000..373d727ab --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,15 @@ +class Event extends Task { + protected String from; + protected String to; + + public Event(String description, String from, String to) { + super(description); + this.from = from; + this.to = to; + } + + @Override + public String toString() { + return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; + } +} From bfd842726734ec4370cbb653bbdb1fb74462ad45 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 05:47:57 +0800 Subject: [PATCH 13/43] Modify toString of Task class --- src/main/java/Task.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 1d00e5b75..735b9cdc9 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -18,4 +18,9 @@ public void markAsDone() { public void markAsUndone() { this.isDone = false; } + + @Override + public String toString() { + return "[" + getStatusIcon() + "] " + description; + } } From b312a64795932aa540247df40994232f2ea6f20d Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 7 Feb 2025 05:48:46 +0800 Subject: [PATCH 14/43] Handle every subclass of Task --- src/main/java/Sparkle.java | 166 +++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 79 deletions(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index 5ecbfc48f..c80a4bf02 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -172,95 +172,103 @@ public static void main(String[] args) { Task[] tasks = new Task[100]; int taskCount = 0; - String userInput = scanner.nextLine(); - while (!userInput.equalsIgnoreCase("bye")) { + while (true) { + String userInput = scanner.nextLine().trim(); + if (userInput.equalsIgnoreCase("bye")) { + System.out.println(" ____________________________________________________________"); + System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); + System.out.println(" ____________________________________________________________"); + break; + } + if (userInput.equalsIgnoreCase("list")) { - System.out.println( - " _________________________________" + "___________________________\n"); - if (taskCount == 0) { - System.out.println(" Looks like there's nothing fun to mess with... How boring!"); - } else { - for (int i = 0; i < taskCount; i++) { - System.out.println( - " " - + (i + 1) - + ". [" - + tasks[i].getStatusIcon() - + "] " - + tasks[i].description - + "~♪"); - } - } - System.out.println( - " _________________________________" + "___________________________\n"); + printTaskList(tasks, taskCount); } else if (userInput.startsWith("mark")) { - int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; - if (taskNumber >= 0 && taskNumber < taskCount) { + handleMarkTask(tasks, taskCount, userInput, true); + } else if (userInput.startsWith("unmark")) { + handleMarkTask(tasks, taskCount, userInput, false); + } else if (userInput.startsWith("todo")) { + String description = userInput.substring(5).trim(); + tasks[taskCount] = new Todo(description); + printAddedTask(tasks[taskCount++], taskCount); + } else if (userInput.startsWith("deadline")) { + String[] parts = userInput.substring(9).split(" /by ", 2); + if (parts.length < 2) { + printInvalidCommandMessage(); + continue; + } + tasks[taskCount] = new Deadline(parts[0].trim(), parts[1].trim()); + printAddedTask(tasks[taskCount++], taskCount); + } else if (userInput.startsWith("event")) { + String[] parts = userInput.substring(6).split(" /from ", 2); + if (parts.length < 2 || !parts[1].contains(" /to ")) { + printInvalidCommandMessage(); + continue; + } + String[] timeParts = parts[1].split(" /to ", 2); + tasks[taskCount] = new Event(parts[0].trim(), timeParts[0].trim(), timeParts[1].trim()); + printAddedTask(tasks[taskCount++], taskCount); + } else { + printInvalidCommandMessage(); + } + } + + scanner.close(); + } + + private static void printTaskList(Task[] tasks, int taskCount) { + System.out.println(" ____________________________________________________________"); + if (taskCount == 0) { + System.out.println(" Looks like there's nothing fun to mess with... How boring!"); + } else { + System.out.println(" Here are the tasks in your list:"); + for (int i = 0; i < taskCount; i++) { + System.out.println(" " + (i + 1) + ". " + tasks[i]); + } + } + System.out.println(" ____________________________________________________________"); + } + + private static void handleMarkTask( + Task[] tasks, int taskCount, String userInput, boolean isMark) { + try { + int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; + if (taskNumber >= 0 && taskNumber < taskCount) { + if (isMark) { tasks[taskNumber].markAsDone(); - System.out.println( - " _____________________________" - + "_______________________________\n" - + " Boom! Task's done and dusted~\n" - + " [" - + tasks[taskNumber].getStatusIcon() - + "] " - + tasks[taskNumber].description - + "\n" - + " _____________________________" - + "_______________________________\n"); + System.out.println(" ____________________________________________________________"); + System.out.println(" Boom! Task's done and dusted~"); } else { - System.out.println( - " _____________________________" - + "_______________________________\n" - + " That task number's playing hide and seek—try again!.\n" - + " _____________________________" - + "_______________________________\n"); - } - } else if (userInput.startsWith("unmark")) { - int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; - if (taskNumber >= 0 && taskNumber < taskCount) { tasks[taskNumber].markAsUndone(); - System.out.println( - " _____________________________" - + "_______________________________\n" - + " Oops! Not done yet, but it's still on the radar!\n" - + " [" - + tasks[taskNumber].getStatusIcon() - + "] " - + tasks[taskNumber].description - + "\n" - + " _____________________________" - + "_______________________________\n"); - } else { - System.out.println( - " _____________________________" - + "_______________________________\n" - + " That task number's playing hide and seek—try again!\n" - + " _____________________________" - + "_______________________________\n"); + System.out.println(" ____________________________________________________________"); + System.out.println(" Not done yet, but it's still on the radar!"); } + System.out.println(" " + tasks[taskNumber]); + System.out.println(" ____________________________________________________________"); } else { - // Add the task if it's not "list" - tasks[taskCount] = new Task(userInput); - taskCount++; - System.out.println( - " _____________________________" - + "_______________________________\n" - + " added: " - + userInput - + "! Let\'s make it fun~" - + "\n" - + " _____________________________" - + "_______________________________\n"); + System.out.println(" ____________________________________________________________"); + System.out.println(" That task number's playing hide and seek—try again!"); + System.out.println(" ____________________________________________________________"); } - userInput = scanner.nextLine(); + } catch (Exception e) { + System.out.println(" ____________________________________________________________"); + System.out.println(" Whoops! That's not a valid input~ Try again!"); + System.out.println(" ____________________________________________________________"); } + } + private static void printAddedTask(Task task, int taskCount) { + System.out.println(" ____________________________________________________________"); + System.out.println(" Let's make it fun! I've added this task:"); + System.out.println(" " + task); System.out.println( - " ____________________________________________________________\n" - + " See you around, Stelle~ Try to stay out of trouble, especially... the next time" - + " we meet!\n" - + " ____________________________________________________________\n"); - scanner.close(); + " Looks like you've got " + taskCount + " tasks in your list~ Better get moving!"); + System.out.println(" ____________________________________________________________"); + } + + private static void printInvalidCommandMessage() { + System.out.println(" ____________________________________________________________"); + System.out.println(" Whoops! That's not a valid input~ Try again!"); + System.out.println(" ____________________________________________________________"); } } From e9c069d070d6de01ae37e3ab64edcfea40eb1477 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 08:27:24 +0800 Subject: [PATCH 15/43] Rewrite logo and refactor command processing --- src/main/java/Sparkle.java | 319 +++++++++++++------------------------ 1 file changed, 108 insertions(+), 211 deletions(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index c80a4bf02..39bc3f836 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -1,223 +1,120 @@ import java.util.Scanner; public class Sparkle { + + static String logo = + "NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN\n" + + "NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN\n" + + "NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN\n" + + "NHZOvz1>>>>>;>;jHMMHHMMHHngHHbkWMMHH@MMMb .dHMs?WmaJJHpHWWMNZzOUUWHHHggkM\n" + + "#Hz>>>>>;>>;;;(MMNqkkkkqHHHHWHHH@@@@MMMM@N. d@MI<~(?>`` ?WHHHN<;<(JHHd@KzM\n" + + "#Hz>;;;<::~~<:~~~:~JMgHppWWWY(dM@MHHH@@MMMHM@@@@N-<(v7<-__ `.-~_(dHkWbpbbbbSM\n" + + "NH>~~:~~~(MmHWWY=(WWHM#XXMH@@H@@@@@@g@@Nv! (61j.~dWWHgHHWWKM\n" + + "#K>~~_jY.(HHWXM@@Mggg@HHgB&HgmgHmmkwXNSWHHWvWYTk-..______~~JMHHggggqHM\n" + + "NK!_..%._(kHWM@@MgmggHH9! (HMHHqqqqgHHHHWHHkUkU9>~~~~~~~~~~(MWHHgggkWM\n" + + "NK_...~.-dHdM@MMgmmgHHm...J0kWHkppkHmHHkHHUKHWm.......-((-_(HNVWHmgHSM\n" + + "NH<...~-JWMHMHHggqgHHYUMMHHwHWHpffppHWpbbbod@g@@M@@@HHMWNmazuHffpHMHXM\n" + + "#HJM@gH:?-``````` `_` `` .! __?~(HgHHkqqkkqHkXfppWHMMMh-jM\n" + + "#HHgmKMHpHHWI;_ jc;;<1d$-.dHHqH$ ``` JY-JWXWVfffWkUUWMMRM\n" + + "NHGdCldgHSXHkWXHR `````jk1<_(jr``.V!?WHH9Y>`` .``` .dpqWbHkWfudkHqTAwM\n" + + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" + + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" + + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; + static String separator = " ____________________________________________________________\n"; + public static void main(String[] args) { Scanner scanner = new Scanner(System.in); - String logo = - "QQQQQQQQQQQQQQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNQQQQQQQQQQQQQQ\n" - + "QQQQQQQQQQNR5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2222222222222222222222222222222248NQQQQQQQQQQ\n" - + "QQQQQQQQNMMwLviiL7TTTT7777cLuozC3CCnjjjuCeAAyt|Lyyeeoe33y4vrrrrrrrrrrrrrrrrrrrr|tvv7t|rrrrrrrrrrrr||vvLTtFSCzeoeyUmm9aCFzzzjjuCC3yyyyyeyIvSMMNQQQQQQQQ\n" - + "QQQQQQNMMgmJiLTTtttttttttttTJX5Aaa444AA22o2AwU4S6PPkP5Pr^SSr^^^^^^^^^^^^^^^^^^rJ^" - + " --^vir^^^^^^rrr1|LtIuyeAOP2PUkZpBBBO954S5XPPkUE9666GGGUYtGgMMNQQQQQQ\n" - + "QQQQNNMMR5TL7TTTttTTT7cLLivv|ia42222oo2oeooooeoSPPkPPm|-tdEer^^^^^^^^^^^^^^^^^ir----" - + " ^r|v^^^^^rr|vLtFCe2AAHGeZPU5ARBBQqU4aS444SSSSSZ5wXPP5FcSRgMMNQQQQ\n" - + "QQNMgRH4JiLLLLivvvv||1rrrrrr^^LE5eoooooeoooooooeo4PhPk^^ko49e^^^^^^^^^^^^^^^^rJ^-----^7Trrvr^^rrr|vvi7tIzs9be2XPkZAURBR6h22AAAAAAAAAAAaaa44ettApRgMNNQ\n" - + "QQRAFTvvv|||rrrrrr^^^^^^^^^^rwevu95oeoeoeeeeeoooeeoaP4ioZooAkC^^^^^^^r|fASaoCAs------^yMHv^rvr^^^rrrrrr|||u8AVZXPEGGSOQqwaaAAAAAAA2AAA2AAAAAAostTI34RQ\n" - + "NQ8J|rrrrr^^^^^^^^^^^^^^^^^eZLTeU88Hmk5SZZ5S4aAAAo2a24LF5oo2Pkr-^rtoSAyA69UU5wT----" - + " -^2R0Q5r^||^^^^^^^^^^^rqEjAwXUGpUSRgh4A4SSSS4aAAAA22222o2222oeLLON\n" - + "NNOJ|^^^^^^^^^^^^^^^^^^^^vZIf98O6kPk9b88mGUkkkVr^rFousttA2oePPlomOO88dGkU88HHpi- " - + " -reRRRNEr^^F5t|r^^^^^-^kHey5wSaGau8Bq3tvctJYzCyeo22o22222222o27cbN\n" - + "NNOJ1^^^^^^^^^^^^^^^^^^^lyF6RbUUmpqG9kw5SSkkkC|3EkXS2ye4422PORRRRR888888OD88Hqv " - + " -ru88RRg9|^^rmmyXUzTvrrG82joSS3jzoRQR2i^rrrrr||viTJIzCVyeeeeeo7cbM\n" - + "NNOJ1^^^^^^^^^^^^^^^^^reyP88mmDEa2AAAaZwPPEUXkqE5Pk99kkUU68RRR8888888OdDO8O88Ov " - + " -^xO888R@kr^^^2gR8R8Fe8OUaujyASSA6qjaPt^-^^^^^^rrrrrr|vLtlIj42LcbM\n" - + "NNOJ1^^^^^^^^^^^^^^^^rXGH8Obmw22222Aa44ZXk6G9UUGmEZa46qO8R8888888ObO8888ObHHb8J- " - + " ^imR88R8f^^^--|mRR5vrv3PkaCje2SkHmYApPr------^^^^^^TA1rrrLUmJ|cbM\n" - + "NNOJr^^^^^^^^^^^^^^^^XQ8bR8ko2A22oo2AAAAAA2Aw9G9E6mUPGO888bHbbHH888HHHHHHbHHHOe- " - + " ^|PR88R4r^^--^^rVv-^^^--^rYuzC24w9PnkOr^^^^-------TPSe^^jEm5|r7bM\n" - + "NNOJr^^^^^^^^^^^^^^-|WWD8H42A2222o2AAAAAAAX66AC5myJw8R8888HHOHbbDdbObbOObHddpbP^ " - + " -rARO88x^^----^r^1v^- -^7jje45k998Gr^^^^^^^-^CZoy5ASGEm2^r7bM\n" - + "NNOJr^^^^^^^^^^^^^^-JB0pw2AA2222222AAa4PUP2jf26srsORR8808bOObO88RRgggRR8888888O| " - + " ----rj888Oj^^^^-^^^^^- - -^tyyA5PUmpC^^^^^^vyZ2o4UmG96UGe^r7bM\n" - + "NNOJ1^^^^^^^^^^^^^-^4RkA4ZZSSSSSZ5Zwkk5yIjCYyI^c8RRR88RR888ObbOO888OHddpppppH8Ra-" - + " ----^Lm8O8UJ^-----^|^ - -rTfoASXEmdy^^ru5SA5UGG9E9GESXx-^TOM\n" - + "NNOJr^^^^^^^^^^-^rJwkShkkPPPPPPPkPPS2C3eF1rTrrGNRR8OR0OGPkGH88888OHDDdppqqqpppbHr" - + " ----^rS8bO8moLr^^rTr -^v22e45kGqksCw4PEPAP6969E52eUT-rTOM\n" - + "NNOJr^^^^^^--^1f56kXkkPkPPPPPPwZ4SSA2jvr^|2^TWRRMgmoFs4m8RR88888HqmqpqppppppdHORa-" - + " ----^lHOdpqHy||x|- - -^ceLLyPPm9AAAAa2^^kG9hAee3Am3LctbM\n" - + "NNOJr^^^^-^T4k9EUEEkGmmGqpHOq6UwaAoyJvv|vA|eMWWmIrvS8gR88888R8pmmmmmmqdODpqpppdbHL-----^rkOmdUr-rrrr-" - + " --^rr^-^e2PGaoG9py-TmX2yyyC2q8bettbM\n" - + "NNOJr^^^^^----^^^^-^4QRbq6pqaoeeyyoVJTccEePMqs^^j8R88OO88888OpmGGGGp88OqmqDDppdHOpr" - + " ----^xPCo|-L|- ^^rLv^--rvfmGz4mkrrP4yyyVekq9EpRetbM\n" - + "NNOJr^^^^-----------uBRD6UdU2oeeye23fxLA8Gz^-|908bHHObqq8888HqmGGHRR8Hmp88dpdpppb8u-----rr---^^|r-" - + " -^vu7r^^^^rnm25s^|96kha2Ak6kE6mb3tbM\n" - + "NNDJ|^^^------------LQRpEGma2eeee2ACYj4ar-^C88OHbHO8PCER888OdmGHR8O8Hq88pmpDpqqqmdq|--^r-^vcvvr--------" - + " -^-^--^--rIpPoiFUwoyy3yyy3Cy3y2ItbM\n" - + "NMdJ1^--------------|MRGkmU22oeeoAA2Sl^-rkR8ObbHO8ktTUR8888Hqd88O88qD8dmqppqmmqmGqO9rr^^v7^-" - + " --^^^----- -^rr----^^repAzky||2233yyyyyyyyyxtbM\n" - + "NNbJ|^--------------rRRUPmw2AeyyAU4|--vSEASmpHb8pnvvlm8888Op88OO8bpb8pmmppqmmmmGGqHH9|rYr-" - + " --io|^--^^--IO2ySa9T^Jk42oeyyyyeoltbM\n" - + "NNbx|---------------^b8PPGa22y4ac^--^vLI46HHb885LvivivldRbH8bHO8HdbHdqmmppmGGG6GmDmpqwl^" - + " -^^^^rrv31^^J52Gq2o9v-zU5kkPwZSZhstbM\n" - + "NMpJ1---------------^k8ZkE24Uer-" - + " -^vAq8G6pH8R8ZzsJcivvvo6bDGHO8HqppHppmmpqGGGGGGmmmpqa^ - " - + " ^^Lr1|Sa4p8kC3oIxkSooAZk9E9jtbM\n" - + "NMmJr----------------AOahmUJ^--r2m8RHkEqdH8888RRRRdFvvvS8oJkd6mHpqpdppmqdqG6G996GUGGmkr" - + " --- - -^---rxCAmHO69kayokHpXS54aSFtbM\n" - + "NMqJr----------------jpqar-^tU80R88Aj9OpDOOO88888Rqt|7qHx|vvvsH8EEbHpGmqpqmGGG9G9GmU6E|" - + " ---- -- ---- ----^fSGmD9PkPZeCySmGP9mmutbM\n" - + "NMpJr----------------jC^^lm00R88RpIVbbDHHdDOOHHbb88AoR9ttCAyY9RmFa8Od6mpppqmGGmmEmGk9GJ-" - + " -^^-- ^vr^--- -------^AqPEPP5eAa2eeyAmpGmutbM\n" - + "NNHJr--------------r|^|U@0RRRRRNGc28HbHpqpObppHbbOEE8H9q888qpOOavIGp6eSqDpqqmmq6EmU9Eme^" - + " ^^^^^--- -rttTvr^- ---^ap24ae4woyeeeeyykDputbM\n" - + "NNOxr------------^|rtpR88888dqRPvA8dHDmmqODmmqdHpGq8pmbOObdH8bGI||vSz||smbpqppqk9P56E6Sr" - + " -^^^^^^^^^^^^----^^^^^^rrrvxI^- ---^A6j2ozyPPAyeeeeyy9OCtbM\n" - + "NNOJr-----------|tFpWR8qEwA3sPP|zHpppmGpbqmmqpDqmHbmmqpDpp8RHmGu||yS||v|c4ddpHmP6ee5UEPt^r7xFYlvr|r^^^^^rrr|LYeaPE69aIvvT-" - + " ---^SkjyFsAwkU52eyeeuAbytbM\n" - + "NNOJr---------^jA9pzrJ54aaozSP1lHpqpmGqqGGGGmpqmHq9U9mmGdmhppmpGntwjitIT||f42llkUnJt9EUPozovrl3CT^lGDqHOOpG5u7v|r|v|vsPa|-----^5Eoyt3wkkkUUk5ao3eqytbM\n" - + "NNbJr---------FpEv---jk4Sa3AUvTdbppmmpq6G6Gmqqmq95wUGk6qx^2O9pq6UmP5mGGGa7||vvzdwVT|XGUmkyev-^e2elCje2r^---" - + " ------^^-----^odUkfCPPkkkkkkUU4e6ytbM\n" - + "NMptr^-------vqt----^Ak44eaGvJ88ppqmbp69E9GmqmqkSk6UGqPTrtmPmGEUUG596kkk9ksvvLaH4yv|A62CV2yeFLs2Jr^rYoz^" - + " ---^^-----------------i8mO9FekUkkkkkkUPek3tbM\n" - + "NMptr^-------h|" - + " ----^5XSAaELC88DppqHH6EEE9GmmqkPkZXGC^--^5mm8GUhUUw9kPPPPk9PAyUp5oj4asyX99E4v^^jIrrrtje|^^^^-------------------^GRGwaeyPkUkkkkkk25jtbM\n" - + "NMpJr-------rJ------ikSA9UvaR8dpDpDbGEUUU9GGmqka56z^-- " - + " ^SSpOUGUGPPkPwZwwPU99Pm9PSUq4lCSXaoooCvjASS3Cui^^-----------------------tgPsooSo4EkPPPPP2astbM\n" - + "NNHJr ------rr---- -oEw8e|UROHHdqHOGUUUUU96mmZ5wt^- " - + " rkaaPh4ZUXP5waa4ZPPkXPpwPwkEU5oCeAkPCXf^Jo2r--- " - + " ----------------------|H8SyzC5aeXkPPkkA2ItbM\n" - + "NNbT^" - + " -------^-----|kqGcjR0bppDH8OG9UkkkUU9Dm4AUCr^-----vUofa5ASka5a422A455w4PmAZXSZ555X9U7e4CPUeePe^^-------------^^^rr^^^^---^5HH8ajuCo5aaPkkk4yJtbM\n" - + "NNbJr-------------^kHuFp0Rbpb8R88m69PU6GqmmHqGmpH8Oqkev^IPsTS425UASAA2y2Aaa4ePGoaZAaS4a4Sk1^4G4a5UqO888ROmmqG99mmpmGwyIv||v|r^^--^i6XuCyyya99PPkwCttbM\n" - + "NNOxr------------^eosGRRR88RRR88H6GUkkkE9mpm6PAoSbOObEGHpwvLk2ePkAAoooye22A2eZZ3AA2a4aa4ASv-^9pqG6GpDdOg8qqmmqmb888ROXSH86wVLrrr^roZ33yyyee2S6q9kATtOM\n" - + "NNbJr----------^ifyG8RRRRR88R888GGqkPPPPkGG6j^--vOma2aaA6mGUay2w4ooy3eyye2AoyFyCoAo2222SA2AztoDGH69mpd8ROppmmmmb8888mUc^e8dbRROPCCt7yeyeyeo22eSmpGltOM\n" - + "NNOJr-rr^^^rrijakp88888888888bmqEqmkPPwPU9lse^ " - + " vpsrrCS|zqpOXjAYJ2oCCCCCye22C|j3e2yeeee5Aat--^COOpU6mqO8DpdmGmDOR88qa2AuIy5q8R8Hzi7lyeeyeeo22o4k6jvtOM\n" - + "NNOxr--rJeX6mqH8ObOOO88888qPoja96bmPwXwPGX^^vi-" - + " ^ji^-^eAitZmPFCTrAAnjjuu3eeaI^teVoCyyyyooAz----n8O8pqmH8pppmmpb8888Vr^-^r|Js9WRRpCJuoeeeeo2222ADA-^tOM\n" - + "NNOJr-----^^^zmGGmH88GkdPyzjeA66mbmPwXwkmU^" - + " -^^--|F^-----^zL^r^--^vYeeyuny24|-|ay2VyyyeLL2o^ -^^SpqOHqdHqdpGmD8R88Ov- " - + " -^rr|TDW88Ujy2yyeeoAA2e5q| ^tOM\n" - + "NNbtr------^l2yoyC4Gk6mAyaw5aa9GpHmPwhhkqp^ - --^^r^r^-rT^ - -^rLC4G2^" - + " ^2nCCjyeAvr35|- --^kHpmmbppHmGpO88H85r^^^^r^^|l6g8ROAe2yeee24aeyGa^ rtOM\n" - + "NNOlt|^-^|A4eA423jZ6h9kS6kSaA4GmDbpk55Pkm2r ----- ----^-- " - + " --r^--^oX4w4A24GGZ5Sv^-^^vRpdqmGDpmpH88qp8yr^^^v^^r|ud8888pS2eeeo2SaVypJ- rtOM\n" - + "NNOxCGqEPaS969Z2njw9Pqp9UkwaeAqpHbH95Zw99Lr - - -L^ " - + " -rv|cXUZkhlzPPmpqqOP|^ebpH9mpmppO8mqpbui|r|fxLF4mq88888qAeeeoAh4uAk^ rtOM\n" - + "NNOJjPSAoyPmXkGmGk99mm99kS2eem8pHHbmw55G9||- " - + " ^E2TxAlF4SS9qmGmwufGd9GqmqmO8GG9HEZ2L2qFvt44PGH8O888EeeooaP4u4A^ rtOM\n" - + "NNOJF4SaSGm6XhPX45Gq66U55XSa6PqHpHHqPww9HPo^ " - + " ^Ir-^Je1|eP6x|oEEGUUEkmGmGp8E9EqqyC2PA5SavT5uoG8OOO8RGee24PSCZJ---rtOM\n" - + "NMHJT|vP8Gk9PXP5XmqmmGGUkkEE7|68mpppUwkG|^rr " - + " ^^-----^uGi--^Ska2PhEGG6pHPPk68wVo2A5Gus1LeAXA4GDHO8RHAoZPSyw|---rtOM\n" - + "NMDJ|LqHmGPEUhZkqpHqG99EEGAvTsCdqdpp6k9kr^^i^ -- " - + " --^^^^vvr--^teIvzkSP66Gpq55wkG6A22A4wquliteyye4wwXEqpO8Hkw42hr --rtOM\n" - + "NNHJybqmm65k65Ppbpaa9E9EmoLVv^^PRqqmm9Ukr^^r|- ------ -^-" - + " --^^^^rt|^-^jwSU99mqk4ZZPU6P2aaaSwmYjJtyyyeeee2hGGqb88RbkXr---rtOM\n" - + "NNbJ3qqm6E5aGwmO9ey5U99p2Lyr^^^v8OG6G6kkr^^^rr- - -- -^- " - + " - ----- -r45P99GmkAa44X55wS4S5SShEYaAlyyyyeeee2Zoe25E6m8qJr^-rtOM\n" - + "NMpJCmmG9kXeXGq92yy4kkqkt2|^^^^^j8mE9U5bT^^^^r|- - " - + " ---- ^jwhEGGE5AAAAAha2Z24S45XwkZy2ya3yyyeeooAw2eoa55wGy- --rtOM\n" - + "NMHJCmG9UPGyrkpaAyu259qLty^^^^^^^U8EEUwbGr^^^^rr^- --- " - + " --^rf59GGEka22AAAAwo3r|ooAa5XPEAwEt4eyyeeeeoAXAe245Zwp2- --rtOM\n" - + "NNOxCG9kP9o^-1mG2ynyap4rTj^^^^^^^LbGkEP9qu^^^^^^^|^ -- " - + " -^|itzo5UUPeie5a4AAaAAaPufr-^3CeAS5wwam8eu4Cyeeee2aPSe2S5w5Go- --rtOM\n" - + "NNOxuUkPmC^-^-|8q2YjaGF^vVr^^^^^^^zdEUX9kkt^^^^^^^r|- ------ " - + " --^|Iv^- ^PZZaAaAa5P3Ir -IyC2aZw4UG9EySCyeeeoA4Pwo2S5556S^ --rtOM\n" - + "NNOJjXk9t^-^^--rGGaz2klrrAv^^^^^^^^2qEP6mP6f^^^^^^|ke^- " - + " ^r1^^^rr1ySS4AAASPUAzr- veu2A4SUpkZG45ACyeeoa4XPA2S555k9| rtOM\n" - + "NNbJj9P|^-^^-- rmSaUUjrrJor^^^^^^^^SqUGkvv2Av^^^^YP|^r- " - + " -^|2i^^^^^^-chAa4A2wkU5ot^^-- |2C2A4kSy4UUZkhnyyeeaShk4ASwwwwG2- ^tOM\n" - + "NNbJVe^^^^^- --- ^Xko5Syv^xyrr^^^^^^^up9qF^rr^^^^|aer^^r^- " - + " ---^|IJrvUF^^^^^^^vS4AaawE999w1- ---^Joy2Ame-^r3m4kPjC3yea5Xkw4S5w5h9mv- ^tOM\n" - + "NNblv^^^^^--^--^^-^ekaS46Us4errr^^^^^^vkkkPCv||^^7hl^^^^^rr^----^^^r|v7xsCoaAIr^iGu^^^^^^^|aSAaPU9UEqe^" - + " -C2e2U3- -L^jEmPzyeo2SwwUPSSw5w9S3kr ^tOM\n" - + "NNOJvr^^^-rr-^^^----r5GkAwkUm4vrrr^^^^^ryPPj^^^" - + " -i4i^^^^^^^rtYJs2SA2eyy3jt1^^-^fEy^^^^^^^v4SAZPkUUmmL- ^5o2Ua^ " - + " ^vtGqmwZSaSZ44ZXkPkkUO9rfa-^tOM\n" - + "NNbtv^^^ r1^^^rr^----^yEPU9UX4PV|rr^^^^^-|zAki-" - + " -vAJ^^^^rr|JfT7i^^r^^^^^^^^^^^jUJ^^^^^^^Jk5ZhPhP9qC^ " - + " TE4kv-rr-^vAauYffFsssssuAASk6UE99E6RAitOM\n" - + "NNOJv^^ -rr^^^^rCyvrr^^F6PXPkk2aAL|r^^^-" - + " ---rJv^-r2i^rrtIvr^^^rv^^^^^^^^^^^^rV2v^^^--^ckk5PkkPUmA^ ^EqP^ " - + " -fPsTxfFsszzzzjzjF7tlF2U6k6mqmbstOM\n" - + "NNbJLr^rv|rrr^^uPS52Yv^-1PaA2eo2yzF|^- ----r2Trt7v^--- -^vv^^^^^^^^^|t2zr-" - + " --rCGU5kUUPkGPr- -eU|- -|oCsJIYYFssjzzjzjjYtlye22eSdOdpDstOM\n" - + "NNbxi|vtu|rrrrv5hPkkytv|vV4e3eAejfeT- " - + " ^3jT||ir^-----^ir^^^^^--^I23oyuy4GGw5kEkPP5jr- --- -rv^ " - + " ^waFAAy442VujnnjsjyeyJv||LlYT|iyUbztOM\n" - + "NQOJT|^|lrrrrrFEPUUolxteAya2sItloejv- -LeTr1vr^^^^^^|t^- -vSY^" - + " -rLAUS4h542Ccr^-- ---- -- ^94CoZAye22AaAA2oAIrrriCFyXZkEAtJvr|tON\n" - + "QQ8YtJLtTr^rrreGkEkjJtJ4S3Aw3TLvilyc- ^as|r|rrvrr1|Jl^ ^Ca|-" - + " -^Lyoe2ezcr^^^^- ------ ^Hk2ya5Z5S4w4oeey2Sr^JezTAaw9hSc^vzl7l8N\n" - + "QQN08dZstL|rrr2Gk6kzt7sS2CA4Af|1||TL- -Torrvietrvir^- " - + " -vAIrrLzAaeCJ|r^^^^^^- ------ " - + " -ADSAVA2y2k5eCCCzFze|^TCESvr1rvlTT3PH80MQ\n" - + "QQQQNNMRmVtTLvAmU6UjtcjAyuAAASu|rrv|- ^2z^^^^^^-- -rAI^ " - + " ------^--^^^-- ------ rDaSSS4ZU5yCy3jFFzsyirTCoXPoT||t2OgMNNQQQ\n" - + "QQQQQQQNNRSxTvVdEGECJcsSojV4a5t^rrLr -LUr -r2u^- -----^^^^----" - + " - ------ -om4S5SU62yooenszssf3t^|oneuTi7lUgMNNQQQQQ\n" - + "QQQQQQQQNMgGlLT9qUG2x7JSS2zICSA^-Jx- ^eo^ -^yer- ------- " - + " - -- ---- ^Gk5kk9SFsnzuCCCe2225y^^jzPi^|J9gNNQQQQQQQ\n" - + "QQQQQQQQQQNWAJtxsIfxtttxlxJttJxLvttv|vvvvvvvvvvvvv||vtl7vvvvv|vJfT||vvv||||||||||vvvvvvvvvvvvv|vvvvvvvvvvvv|iltxfFYJttttJttttJJxIlTvTtTLvTAgNQQQQQQQQQ\n" - + "QQQQQQQQQQQNg888RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR8RRR8RRRRRRRRRRRRRR8RR8RRR8RgQQQQQQQQQQQ"; - - System.out.println( - " _____________________________" - + "_______________________________\n" - + " Hey hey, I'm Sparkle!\n" - + " _____________________________" - + "_______________________________\n" - + "\n" - + logo); + System.out.println(separator + " Hey hey, I'm Sparkle!\n" + separator + "\n" + logo); System.out.println( - " _____________________________" - + "_______________________________\n" - + " Got any cool, daring quests or risky biz? Just hit me up!\n" - + " _____________________________" - + "_______________________________\n"); + separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); Task[] tasks = new Task[100]; int taskCount = 0; while (true) { String userInput = scanner.nextLine().trim(); - if (userInput.equalsIgnoreCase("bye")) { - System.out.println(" ____________________________________________________________"); - System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); - System.out.println(" ____________________________________________________________"); - break; - } + String[] commandParts = userInput.split(" ", 2); + String command = commandParts[0].toLowerCase(); + String details = commandParts.length > 1 ? commandParts[1].trim() : ""; - if (userInput.equalsIgnoreCase("list")) { - printTaskList(tasks, taskCount); - } else if (userInput.startsWith("mark")) { - handleMarkTask(tasks, taskCount, userInput, true); - } else if (userInput.startsWith("unmark")) { - handleMarkTask(tasks, taskCount, userInput, false); - } else if (userInput.startsWith("todo")) { - String description = userInput.substring(5).trim(); - tasks[taskCount] = new Todo(description); - printAddedTask(tasks[taskCount++], taskCount); - } else if (userInput.startsWith("deadline")) { - String[] parts = userInput.substring(9).split(" /by ", 2); - if (parts.length < 2) { - printInvalidCommandMessage(); - continue; - } - tasks[taskCount] = new Deadline(parts[0].trim(), parts[1].trim()); - printAddedTask(tasks[taskCount++], taskCount); - } else if (userInput.startsWith("event")) { - String[] parts = userInput.substring(6).split(" /from ", 2); - if (parts.length < 2 || !parts[1].contains(" /to ")) { + switch (command) { + case "bye": + System.out.print(separator); + System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); + System.out.print(separator); + scanner.close(); + return; + + case "list": + printTaskList(tasks, taskCount); + break; + + case "mark": + case "unmark": + handleMarkTask(tasks, taskCount, details, command.equals("mark")); + break; + + case "todo": + if (details.isEmpty()) { + printInvalidCommandMessage(); + } else { + tasks[taskCount] = new Todo(details); + printAddedTask(tasks[taskCount++], taskCount); + } + break; + + case "deadline": + String[] deadlineParts = details.split(" /by ", 2); + if (deadlineParts.length < 2) { + printInvalidCommandMessage(); + } else { + tasks[taskCount] = new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim()); + printAddedTask(tasks[taskCount++], taskCount); + } + break; + + case "event": + String[] eventParts = details.split(" /from ", 2); + if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { + printInvalidCommandMessage(); + } else { + String[] timeParts = eventParts[1].split(" /to ", 2); + tasks[taskCount] = + new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim()); + printAddedTask(tasks[taskCount++], taskCount); + } + break; + + default: printInvalidCommandMessage(); - continue; - } - String[] timeParts = parts[1].split(" /to ", 2); - tasks[taskCount] = new Event(parts[0].trim(), timeParts[0].trim(), timeParts[1].trim()); - printAddedTask(tasks[taskCount++], taskCount); - } else { - printInvalidCommandMessage(); } } - - scanner.close(); } private static void printTaskList(Task[] tasks, int taskCount) { - System.out.println(" ____________________________________________________________"); + System.out.print(separator); if (taskCount == 0) { System.out.println(" Looks like there's nothing fun to mess with... How boring!"); } else { @@ -226,7 +123,7 @@ private static void printTaskList(Task[] tasks, int taskCount) { System.out.println(" " + (i + 1) + ". " + tasks[i]); } } - System.out.println(" ____________________________________________________________"); + System.out.print(separator); } private static void handleMarkTask( @@ -236,39 +133,39 @@ private static void handleMarkTask( if (taskNumber >= 0 && taskNumber < taskCount) { if (isMark) { tasks[taskNumber].markAsDone(); - System.out.println(" ____________________________________________________________"); + System.out.print(separator); System.out.println(" Boom! Task's done and dusted~"); } else { tasks[taskNumber].markAsUndone(); - System.out.println(" ____________________________________________________________"); + System.out.print(separator); System.out.println(" Not done yet, but it's still on the radar!"); } System.out.println(" " + tasks[taskNumber]); - System.out.println(" ____________________________________________________________"); + System.out.print(separator); } else { - System.out.println(" ____________________________________________________________"); + System.out.print(separator); System.out.println(" That task number's playing hide and seek—try again!"); - System.out.println(" ____________________________________________________________"); + System.out.print(separator); } } catch (Exception e) { - System.out.println(" ____________________________________________________________"); + System.out.print(separator); System.out.println(" Whoops! That's not a valid input~ Try again!"); - System.out.println(" ____________________________________________________________"); + System.out.print(separator); } } private static void printAddedTask(Task task, int taskCount) { - System.out.println(" ____________________________________________________________"); + System.out.print(separator); System.out.println(" Let's make it fun! I've added this task:"); System.out.println(" " + task); System.out.println( " Looks like you've got " + taskCount + " tasks in your list~ Better get moving!"); - System.out.println(" ____________________________________________________________"); + System.out.print(separator); } private static void printInvalidCommandMessage() { - System.out.println(" ____________________________________________________________"); + System.out.print(separator); System.out.println(" Whoops! That's not a valid input~ Try again!"); - System.out.println(" ____________________________________________________________"); + System.out.print(separator); } } From ff61e51f3f45ff78f7254a2c4dfcd2695492f882 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 10:21:49 +0800 Subject: [PATCH 16/43] Handle index error and fix separator --- src/main/java/Sparkle.java | 63 ++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index 39bc3f836..17742e9b4 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -63,7 +63,7 @@ public static void main(String[] args) { case "bye": System.out.print(separator); System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); - System.out.print(separator); + System.out.println(separator); scanner.close(); return; @@ -72,8 +72,11 @@ public static void main(String[] args) { break; case "mark": + handleMarkTask(tasks, taskCount, details, true); + break; + case "unmark": - handleMarkTask(tasks, taskCount, details, command.equals("mark")); + handleMarkTask(tasks, taskCount, details, false); break; case "todo": @@ -118,39 +121,39 @@ private static void printTaskList(Task[] tasks, int taskCount) { if (taskCount == 0) { System.out.println(" Looks like there's nothing fun to mess with... How boring!"); } else { - System.out.println(" Here are the tasks in your list:"); + System.out.println(" Here are the tasks in your list~ "); for (int i = 0; i < taskCount; i++) { System.out.println(" " + (i + 1) + ". " + tasks[i]); } } - System.out.print(separator); + System.out.println(separator); } - private static void handleMarkTask( - Task[] tasks, int taskCount, String userInput, boolean isMark) { + private static void handleMarkTask(Task[] tasks, int taskCount, String input, boolean isMark) { + Integer taskIndex = parseTaskIndex(input, taskCount); + if (taskIndex == null) { + printInvalidCommandMessage(); + return; + } + + Task task = tasks[taskIndex]; + if (isMark) { + task.markAsDone(); + System.out.println(separator + " Boom! Task's done and dusted~"); + } else { + task.markAsUndone(); + System.out.println(separator + " Not done yet, but it's still on the radar!"); + } + System.out.println(" " + task); + System.out.println(separator); + } + + private static Integer parseTaskIndex(String input, int size) { try { - int taskNumber = Integer.parseInt(userInput.split(" ")[1]) - 1; - if (taskNumber >= 0 && taskNumber < taskCount) { - if (isMark) { - tasks[taskNumber].markAsDone(); - System.out.print(separator); - System.out.println(" Boom! Task's done and dusted~"); - } else { - tasks[taskNumber].markAsUndone(); - System.out.print(separator); - System.out.println(" Not done yet, but it's still on the radar!"); - } - System.out.println(" " + tasks[taskNumber]); - System.out.print(separator); - } else { - System.out.print(separator); - System.out.println(" That task number's playing hide and seek—try again!"); - System.out.print(separator); - } - } catch (Exception e) { - System.out.print(separator); - System.out.println(" Whoops! That's not a valid input~ Try again!"); - System.out.print(separator); + int taskNumber = Integer.parseInt(input) - 1; + return (taskNumber >= 0 && taskNumber < size) ? taskNumber : null; + } catch (NumberFormatException e) { + return null; } } @@ -160,12 +163,12 @@ private static void printAddedTask(Task task, int taskCount) { System.out.println(" " + task); System.out.println( " Looks like you've got " + taskCount + " tasks in your list~ Better get moving!"); - System.out.print(separator); + System.out.println(separator); } private static void printInvalidCommandMessage() { System.out.print(separator); System.out.println(" Whoops! That's not a valid input~ Try again!"); - System.out.print(separator); + System.out.println(separator); } } From fa98ad4fa113bb5b87ab62d79aa6bba433560de0 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 10:22:13 +0800 Subject: [PATCH 17/43] Change the name of class --- text-ui-test/runtest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index c9ec87003..0151292c5 100644 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -20,7 +20,7 @@ then fi # run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT -java -classpath ../bin Duke < input.txt > ACTUAL.TXT +java -classpath ../bin Sparkle < input.txt > ACTUAL.TXT # convert to UNIX format cp EXPECTED.TXT EXPECTED-UNIX.TXT From 0fbb3210e41581c7ba745967570374540ca94bd5 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 10:36:46 +0800 Subject: [PATCH 18/43] Create the automation for test --- text-ui-test/EXPECTED.TXT | 88 ++++++++++++++++++++++++++++++++++++--- text-ui-test/input.txt | 7 ++++ text-ui-test/runtest.sh | 0 3 files changed, 89 insertions(+), 6 deletions(-) mode change 100644 => 100755 text-ui-test/runtest.sh diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e..51e632d16 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,83 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| + ____________________________________________________________ + Hey hey, I'm Sparkle! + ____________________________________________________________ + +NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN +NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN +NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN +NHZOvz1>>>>>;>;jHMMHHMMHHngHHbkWMMHH@MMMb .dHMs?WmaJJHpHWWMNZzOUUWHHHggkM +#Hz>>>>>;>>;;;(MMNqkkkkqHHHHWHHH@@@@MMMM@N. d@MI<~(?>`` ?WHHHN<;<(JHHd@KzM +#Hz>;;;<::~~<:~~~:~JMgHppWWWY(dM@MHHH@@MMMHM@@@@N-<(v7<-__ `.-~_(dHkWbpbbbbSM +NH>~~:~~~(MmHWWY=(WWHM#XXMH@@H@@@@@@g@@Nv! (61j.~dWWHgHHWWKM +#K>~~_jY.(HHWXM@@Mggg@HHgB&HgmgHmmkwXNSWHHWvWYTk-..______~~JMHHggggqHM +NK!_..%._(kHWM@@MgmggHH9! (HMHHqqqqgHHHHWHHkUkU9>~~~~~~~~~~(MWHHgggkWM +NK_...~.-dHdM@MMgmmgHHm...J0kWHkppkHmHHkHHUKHWm.......-((-_(HNVWHmgHSM +NH<...~-JWMHMHHggqgHHYUMMHHwHWHpffppHWpbbbod@g@@M@@@HHMWNmazuHffpHMHXM +#HJM@gH:?-``````` `_` `` .! __?~(HgHHkqqkkqHkXfppWHMMMh-jM +#HHgmKMHpHHWI;_ jc;;<1d$-.dHHqH$ ``` JY-JWXWVfffWkUUWMMRM +NHGdCldgHSXHkWXHR `````jk1<_(jr``.V!?WHH9Y>`` .``` .dpqWbHkWfudkHqTAwM +NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN +NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN +NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN + ____________________________________________________________ + Got any cool, daring quests or risky biz? Just hit me up! + ____________________________________________________________ + + ____________________________________________________________ + Let's make it fun! I've added this task: + [T][ ] Buy milk + Looks like you've got 1 tasks in your list~ Better get moving! + ____________________________________________________________ + + ____________________________________________________________ + Let's make it fun! I've added this task: + [D][ ] Submit assignment (by: 2025-02-20) + Looks like you've got 2 tasks in your list~ Better get moving! + ____________________________________________________________ + + ____________________________________________________________ + Let's make it fun! I've added this task: + [E][ ] Project meeting (from: 2pm to: 4pm) + Looks like you've got 3 tasks in your list~ Better get moving! + ____________________________________________________________ + + ____________________________________________________________ + Here are the tasks in your list~ + 1. [T][ ] Buy milk + 2. [D][ ] Submit assignment (by: 2025-02-20) + 3. [E][ ] Project meeting (from: 2pm to: 4pm) + ____________________________________________________________ + + ____________________________________________________________ + Boom! Task's done and dusted~ + [D][X] Submit assignment (by: 2025-02-20) + ____________________________________________________________ + + ____________________________________________________________ + Not done yet, but it's still on the radar! + [D][ ] Submit assignment (by: 2025-02-20) + ____________________________________________________________ + + ____________________________________________________________ + See you around, Stelle~ Try to stay out of trouble next time! + ____________________________________________________________ diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb..b175ab883 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,7 @@ +todo Buy milk +deadline Submit assignment /by 2025-02-20 +event Project meeting /from 2pm /to 4pm +list +mark 2 +unmark 2 +bye diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh old mode 100644 new mode 100755 From 0df253b4e30d924c89ed55145deb3ffbdbd9732a Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 11:46:46 +0800 Subject: [PATCH 19/43] Refactor error handling: unify exceptions under SparkleException --- src/main/java/Sparkle.java | 136 ++++++++++++++-------------- src/main/java/SparkleException.java | 29 ++++++ 2 files changed, 98 insertions(+), 67 deletions(-) create mode 100644 src/main/java/SparkleException.java diff --git a/src/main/java/Sparkle.java b/src/main/java/Sparkle.java index 17742e9b4..3214c680c 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/Sparkle.java @@ -54,64 +54,62 @@ public static void main(String[] args) { int taskCount = 0; while (true) { - String userInput = scanner.nextLine().trim(); - String[] commandParts = userInput.split(" ", 2); - String command = commandParts[0].toLowerCase(); - String details = commandParts.length > 1 ? commandParts[1].trim() : ""; - - switch (command) { - case "bye": - System.out.print(separator); - System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); - System.out.println(separator); - scanner.close(); - return; - - case "list": - printTaskList(tasks, taskCount); - break; - - case "mark": - handleMarkTask(tasks, taskCount, details, true); - break; - - case "unmark": - handleMarkTask(tasks, taskCount, details, false); - break; - - case "todo": - if (details.isEmpty()) { - printInvalidCommandMessage(); - } else { + try { + String userInput = scanner.nextLine().trim(); + String[] commandParts = userInput.split(" ", 2); + String command = commandParts[0].toLowerCase(); + String details = commandParts.length > 1 ? commandParts[1].trim() : ""; + + switch (command) { + case "bye": + System.out.print(separator); + System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); + System.out.println(separator); + scanner.close(); + return; + + case "list": + printTaskList(tasks, taskCount); + break; + + case "mark": + case "unmark": + handleMarkTask(tasks, taskCount, details, command.equals("mark")); + break; + + case "todo": + if (details.isEmpty()) + throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); tasks[taskCount] = new Todo(details); printAddedTask(tasks[taskCount++], taskCount); - } - break; - - case "deadline": - String[] deadlineParts = details.split(" /by ", 2); - if (deadlineParts.length < 2) { - printInvalidCommandMessage(); - } else { + break; + + case "deadline": + String[] deadlineParts = details.split(" /by ", 2); + if (deadlineParts.length < 2) + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, "Deadline requires a /by time."); tasks[taskCount] = new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim()); printAddedTask(tasks[taskCount++], taskCount); - } - break; - - case "event": - String[] eventParts = details.split(" /from ", 2); - if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { - printInvalidCommandMessage(); - } else { + break; + + case "event": + String[] eventParts = details.split(" /from ", 2); + if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, "Event requires /from and /to time."); + } String[] timeParts = eventParts[1].split(" /to ", 2); tasks[taskCount] = new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim()); printAddedTask(tasks[taskCount++], taskCount); - } - break; + break; - default: - printInvalidCommandMessage(); + default: + throw new SparkleException(SparkleException.ErrorType.UNKNOWN_COMMAND, command); + } + } catch (SparkleException e) { + printErrorMessage(e.getMessage()); } } } @@ -129,23 +127,27 @@ private static void printTaskList(Task[] tasks, int taskCount) { System.out.println(separator); } - private static void handleMarkTask(Task[] tasks, int taskCount, String input, boolean isMark) { - Integer taskIndex = parseTaskIndex(input, taskCount); - if (taskIndex == null) { - printInvalidCommandMessage(); - return; - } - - Task task = tasks[taskIndex]; - if (isMark) { - task.markAsDone(); - System.out.println(separator + " Boom! Task's done and dusted~"); - } else { - task.markAsUndone(); - System.out.println(separator + " Not done yet, but it's still on the radar!"); + private static void handleMarkTask(Task[] tasks, int taskCount, String userInput, boolean isMark) + throws SparkleException { + try { + int taskNumber = Integer.parseInt(userInput) - 1; + if (taskNumber < 0 || taskNumber >= taskCount) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); + } + if (isMark) { + tasks[taskNumber].markAsDone(); + System.out.print(separator); + System.out.println(" Boom! Task's done and dusted~"); + } else { + tasks[taskNumber].markAsUndone(); + System.out.print(separator); + System.out.println(" Not done yet, but it's still on the radar!"); + } + System.out.println(" " + tasks[taskNumber]); + System.out.print(separator); + } catch (NumberFormatException e) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } - System.out.println(" " + task); - System.out.println(separator); } private static Integer parseTaskIndex(String input, int size) { @@ -166,9 +168,9 @@ private static void printAddedTask(Task task, int taskCount) { System.out.println(separator); } - private static void printInvalidCommandMessage() { + private static void printErrorMessage(String message) { System.out.print(separator); - System.out.println(" Whoops! That's not a valid input~ Try again!"); + System.out.println(" Whoops! " + message); System.out.println(separator); } } diff --git a/src/main/java/SparkleException.java b/src/main/java/SparkleException.java new file mode 100644 index 000000000..a23af9742 --- /dev/null +++ b/src/main/java/SparkleException.java @@ -0,0 +1,29 @@ +class SparkleException extends Exception { + + public enum ErrorType { + EMPTY_TASK_DESCRIPTION, + UNKNOWN_COMMAND, + INVALID_TASK_NUMBER, + INVALID_FORMAT + } + + public SparkleException(ErrorType type, String details) { + super(generateMessage(type, details)); + } + + private static String generateMessage(ErrorType type, String details) { + switch (type) { + case EMPTY_TASK_DESCRIPTION: + return details + + " Nothing in the description! At least give me some fireworks to set off..."; + case UNKNOWN_COMMAND: + return details + "? Huh? That's just noise! Say something that actually makes sense~"; + case INVALID_TASK_NUMBER: + return "That task number's playing hide and seek~ Try again!"; + case INVALID_FORMAT: + return details; + default: + return "An unknown error occurred."; + } + } +} From d88ca445272988acf7145b923ca22387f1083237 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 12:02:11 +0800 Subject: [PATCH 20/43] Refactor project structure and packaging --- src/main/java/{ => sparkle/core}/Sparkle.java | 18 ++++++++---------- .../exception}/SparkleException.java | 4 +++- src/main/java/{ => sparkle/task}/Deadline.java | 2 ++ src/main/java/{ => sparkle/task}/Event.java | 4 +++- src/main/java/{ => sparkle/task}/Task.java | 2 ++ src/main/java/{ => sparkle/task}/Todo.java | 2 ++ 6 files changed, 20 insertions(+), 12 deletions(-) rename src/main/java/{ => sparkle/core}/Sparkle.java (96%) rename src/main/java/{ => sparkle/exception}/SparkleException.java (91%) rename src/main/java/{ => sparkle/task}/Deadline.java (92%) rename src/main/java/{ => sparkle/task}/Event.java (84%) rename src/main/java/{ => sparkle/task}/Task.java (96%) rename src/main/java/{ => sparkle/task}/Todo.java (88%) diff --git a/src/main/java/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java similarity index 96% rename from src/main/java/Sparkle.java rename to src/main/java/sparkle/core/Sparkle.java index 3214c680c..5dc251e34 100644 --- a/src/main/java/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -1,4 +1,11 @@ +package sparkle.core; + import java.util.Scanner; +import sparkle.exception.SparkleException; +import sparkle.task.Deadline; +import sparkle.task.Event; +import sparkle.task.Task; +import sparkle.task.Todo; public class Sparkle { @@ -144,21 +151,12 @@ private static void handleMarkTask(Task[] tasks, int taskCount, String userInput System.out.println(" Not done yet, but it's still on the radar!"); } System.out.println(" " + tasks[taskNumber]); - System.out.print(separator); + System.out.println(separator); } catch (NumberFormatException e) { throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } } - private static Integer parseTaskIndex(String input, int size) { - try { - int taskNumber = Integer.parseInt(input) - 1; - return (taskNumber >= 0 && taskNumber < size) ? taskNumber : null; - } catch (NumberFormatException e) { - return null; - } - } - private static void printAddedTask(Task task, int taskCount) { System.out.print(separator); System.out.println(" Let's make it fun! I've added this task:"); diff --git a/src/main/java/SparkleException.java b/src/main/java/sparkle/exception/SparkleException.java similarity index 91% rename from src/main/java/SparkleException.java rename to src/main/java/sparkle/exception/SparkleException.java index a23af9742..ce36e697b 100644 --- a/src/main/java/SparkleException.java +++ b/src/main/java/sparkle/exception/SparkleException.java @@ -1,4 +1,6 @@ -class SparkleException extends Exception { +package sparkle.exception; + +public class SparkleException extends Exception { public enum ErrorType { EMPTY_TASK_DESCRIPTION, diff --git a/src/main/java/Deadline.java b/src/main/java/sparkle/task/Deadline.java similarity index 92% rename from src/main/java/Deadline.java rename to src/main/java/sparkle/task/Deadline.java index aabb0f016..25f495f8b 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/sparkle/task/Deadline.java @@ -1,3 +1,5 @@ +package sparkle.task; + public class Deadline extends Task { protected String by; diff --git a/src/main/java/Event.java b/src/main/java/sparkle/task/Event.java similarity index 84% rename from src/main/java/Event.java rename to src/main/java/sparkle/task/Event.java index 373d727ab..1b20de527 100644 --- a/src/main/java/Event.java +++ b/src/main/java/sparkle/task/Event.java @@ -1,4 +1,6 @@ -class Event extends Task { +package sparkle.task; + +public class Event extends Task { protected String from; protected String to; diff --git a/src/main/java/Task.java b/src/main/java/sparkle/task/Task.java similarity index 96% rename from src/main/java/Task.java rename to src/main/java/sparkle/task/Task.java index 735b9cdc9..faf3d19ff 100644 --- a/src/main/java/Task.java +++ b/src/main/java/sparkle/task/Task.java @@ -1,3 +1,5 @@ +package sparkle; + public class Task { protected String description; protected boolean isDone; diff --git a/src/main/java/Todo.java b/src/main/java/sparkle/task/Todo.java similarity index 88% rename from src/main/java/Todo.java rename to src/main/java/sparkle/task/Todo.java index 4db97d719..1f3326c9e 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/sparkle/task/Todo.java @@ -1,3 +1,5 @@ +package sparkle.task; + public class Todo extends Task { public Todo(String description) { super(description); From 9c13e53cf9ee3446409af2237e62c21192b7c417 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 12:48:03 +0800 Subject: [PATCH 21/43] Add error handling to deadline and event --- src/main/java/sparkle/core/Sparkle.java | 6 ++++++ src/main/java/sparkle/exception/SparkleException.java | 2 +- src/main/java/sparkle/task/Task.java | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index 5dc251e34..a45713618 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -92,6 +92,9 @@ public static void main(String[] args) { break; case "deadline": + if (details.isEmpty()) + throw new SparkleException( + SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Deadline"); String[] deadlineParts = details.split(" /by ", 2); if (deadlineParts.length < 2) throw new SparkleException( @@ -101,6 +104,9 @@ public static void main(String[] args) { break; case "event": + if (details.isEmpty()) + throw new SparkleException( + SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Event"); String[] eventParts = details.split(" /from ", 2); if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { throw new SparkleException( diff --git a/src/main/java/sparkle/exception/SparkleException.java b/src/main/java/sparkle/exception/SparkleException.java index ce36e697b..9106518ad 100644 --- a/src/main/java/sparkle/exception/SparkleException.java +++ b/src/main/java/sparkle/exception/SparkleException.java @@ -25,7 +25,7 @@ private static String generateMessage(ErrorType type, String details) { case INVALID_FORMAT: return details; default: - return "An unknown error occurred."; + return "A little chaos just slipped in—was that your plan?"; } } } diff --git a/src/main/java/sparkle/task/Task.java b/src/main/java/sparkle/task/Task.java index faf3d19ff..daa55e849 100644 --- a/src/main/java/sparkle/task/Task.java +++ b/src/main/java/sparkle/task/Task.java @@ -1,4 +1,4 @@ -package sparkle; +package sparkle.task; public class Task { protected String description; From c1090cf3094ba7f8445d4cb79dad7b9c6bb85239 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 12:55:45 +0800 Subject: [PATCH 22/43] Adjust paths in runtest.sh to match the updated packaging structure and change the expected text to updated one --- text-ui-test/EXPECTED.TXT | 52 +++++++++++++++++++++++++++++++++++---- text-ui-test/input.txt | 14 ++++++++--- text-ui-test/runtest.sh | 4 +-- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 51e632d16..77a242ffe 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -44,7 +44,7 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ Let's make it fun! I've added this task: - [T][ ] Buy milk + [T][ ] Buy groceries Looks like you've got 1 tasks in your list~ Better get moving! ____________________________________________________________ @@ -54,17 +54,30 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN Looks like you've got 2 tasks in your list~ Better get moving! ____________________________________________________________ + ____________________________________________________________ + Whoops! Todo Nothing in the description! At least give me some fireworks to set off... + ____________________________________________________________ + ____________________________________________________________ Let's make it fun! I've added this task: - [E][ ] Project meeting (from: 2pm to: 4pm) + [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) Looks like you've got 3 tasks in your list~ Better get moving! ____________________________________________________________ + ____________________________________________________________ + Whoops! Event requires /from and /to time. + ____________________________________________________________ + ____________________________________________________________ Here are the tasks in your list~ - 1. [T][ ] Buy milk + 1. [T][ ] Buy groceries 2. [D][ ] Submit assignment (by: 2025-02-20) - 3. [E][ ] Project meeting (from: 2pm to: 4pm) + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + ____________________________________________________________ + + ____________________________________________________________ + Boom! Task's done and dusted~ + [T][X] Buy groceries ____________________________________________________________ ____________________________________________________________ @@ -72,9 +85,38 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN [D][X] Submit assignment (by: 2025-02-20) ____________________________________________________________ + ____________________________________________________________ + Whoops! That task number's playing hide and seek~ Try again! + ____________________________________________________________ + + ____________________________________________________________ + Here are the tasks in your list~ + 1. [T][X] Buy groceries + 2. [D][X] Submit assignment (by: 2025-02-20) + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + ____________________________________________________________ + ____________________________________________________________ Not done yet, but it's still on the radar! - [D][ ] Submit assignment (by: 2025-02-20) + [T][ ] Buy groceries + ____________________________________________________________ + + ____________________________________________________________ + Here are the tasks in your list~ + 1. [T][ ] Buy groceries + 2. [D][X] Submit assignment (by: 2025-02-20) + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + ____________________________________________________________ + + ____________________________________________________________ + Whoops! add? Huh? That's just noise! Say something that actually makes sense~ + ____________________________________________________________ + + ____________________________________________________________ + Here are the tasks in your list~ + 1. [T][ ] Buy groceries + 2. [D][X] Submit assignment (by: 2025-02-20) + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index b175ab883..5207e7b4e 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,7 +1,15 @@ -todo Buy milk +todo Buy groceries deadline Submit assignment /by 2025-02-20 -event Project meeting /from 2pm /to 4pm +todo +event Meeting /from 2025-02-15 10:00 /to 2025-02-15 12:00 +event Movie /from 2025-02-18 15:00 list +mark 1 mark 2 -unmark 2 +mark 10 +list +unmark 1 +list +add something +list bye diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index 0151292c5..177de7c0b 100755 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -13,14 +13,14 @@ then fi # compile the code into the bin folder, terminates if error occurred -if ! javac -cp ../src/main/java -Xlint:none -d ../bin ../src/main/java/*.java +if ! javac -cp ../src/main/java -Xlint:none -d ../bin ../src/main/java/sparkle/**/*.java then echo "********** BUILD FAILURE **********" exit 1 fi # run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT -java -classpath ../bin Sparkle < input.txt > ACTUAL.TXT +java -classpath ../bin sparkle.core.Sparkle < input.txt > ACTUAL.TXT # convert to UNIX format cp EXPECTED.TXT EXPECTED-UNIX.TXT From 7948684a3ca39c803eb2724987568f8d1e352f75 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Feb 2025 13:04:37 +0800 Subject: [PATCH 23/43] Adjust line length in commit message for better readability --- src/main/java/sparkle/exception/SparkleException.java | 4 ++-- text-ui-test/EXPECTED.TXT | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/sparkle/exception/SparkleException.java b/src/main/java/sparkle/exception/SparkleException.java index 9106518ad..1e49b1ff7 100644 --- a/src/main/java/sparkle/exception/SparkleException.java +++ b/src/main/java/sparkle/exception/SparkleException.java @@ -17,9 +17,9 @@ private static String generateMessage(ErrorType type, String details) { switch (type) { case EMPTY_TASK_DESCRIPTION: return details - + " Nothing in the description! At least give me some fireworks to set off..."; + + " has nothing in the description!\n At least give me some fireworks to set off..."; case UNKNOWN_COMMAND: - return details + "? Huh? That's just noise! Say something that actually makes sense~"; + return details + "? Huh? That's just noise!\n Say something that actually makes sense~"; case INVALID_TASK_NUMBER: return "That task number's playing hide and seek~ Try again!"; case INVALID_FORMAT: diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 77a242ffe..12c5497b4 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -55,7 +55,8 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Whoops! Todo Nothing in the description! At least give me some fireworks to set off... + Whoops! Todo has nothing in the description! + At least give me some fireworks to set off... ____________________________________________________________ ____________________________________________________________ @@ -109,7 +110,8 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Whoops! add? Huh? That's just noise! Say something that actually makes sense~ + Whoops! add? Huh? That's just noise! + Say something that actually makes sense~ ____________________________________________________________ ____________________________________________________________ From 3726c582454e30bcacda0994e611188950803f1d Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 04:28:09 +0800 Subject: [PATCH 24/43] Delete function to remove tasks and change tasks to Arraylist --- src/main/java/sparkle/core/Sparkle.java | 60 ++++++++++++++++--------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index a45713618..513a76850 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -1,5 +1,6 @@ package sparkle.core; +import java.util.ArrayList; import java.util.Scanner; import sparkle.exception.SparkleException; import sparkle.task.Deadline; @@ -57,8 +58,7 @@ public static void main(String[] args) { System.out.println( separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); - Task[] tasks = new Task[100]; - int taskCount = 0; + ArrayList tasks = new ArrayList<>(); while (true) { try { @@ -76,19 +76,23 @@ public static void main(String[] args) { return; case "list": - printTaskList(tasks, taskCount); + printTaskList(tasks); + break; + + case "delete": + deleteTask(tasks, details); break; case "mark": case "unmark": - handleMarkTask(tasks, taskCount, details, command.equals("mark")); + handleMarkTask(tasks, details, command.equals("mark")); break; case "todo": if (details.isEmpty()) throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); - tasks[taskCount] = new Todo(details); - printAddedTask(tasks[taskCount++], taskCount); + tasks.add(new Todo(details)); + printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); break; case "deadline": @@ -99,8 +103,8 @@ public static void main(String[] args) { if (deadlineParts.length < 2) throw new SparkleException( SparkleException.ErrorType.INVALID_FORMAT, "Deadline requires a /by time."); - tasks[taskCount] = new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim()); - printAddedTask(tasks[taskCount++], taskCount); + tasks.add(new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim())); + printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); break; case "event": @@ -113,9 +117,8 @@ public static void main(String[] args) { SparkleException.ErrorType.INVALID_FORMAT, "Event requires /from and /to time."); } String[] timeParts = eventParts[1].split(" /to ", 2); - tasks[taskCount] = - new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim()); - printAddedTask(tasks[taskCount++], taskCount); + tasks.add(new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); + printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); break; default: @@ -127,36 +130,53 @@ public static void main(String[] args) { } } - private static void printTaskList(Task[] tasks, int taskCount) { + private static void printTaskList(ArrayList tasks) { System.out.print(separator); - if (taskCount == 0) { + if (tasks.isEmpty()) { System.out.println(" Looks like there's nothing fun to mess with... How boring!"); } else { System.out.println(" Here are the tasks in your list~ "); - for (int i = 0; i < taskCount; i++) { - System.out.println(" " + (i + 1) + ". " + tasks[i]); + for (int i = 0; i < tasks.size(); i++) { + System.out.println(" " + (i + 1) + ". " + tasks.get(i)); } } System.out.println(separator); } - private static void handleMarkTask(Task[] tasks, int taskCount, String userInput, boolean isMark) + private static void handleMarkTask(ArrayList tasks, String userInput, boolean isMark) throws SparkleException { try { int taskNumber = Integer.parseInt(userInput) - 1; - if (taskNumber < 0 || taskNumber >= taskCount) { + if (taskNumber < 0 || taskNumber >= tasks.size()) { throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } if (isMark) { - tasks[taskNumber].markAsDone(); + tasks.get(taskNumber).markAsDone(); System.out.print(separator); System.out.println(" Boom! Task's done and dusted~"); } else { - tasks[taskNumber].markAsUndone(); + tasks.get(taskNumber).markAsUndone(); System.out.print(separator); System.out.println(" Not done yet, but it's still on the radar!"); } - System.out.println(" " + tasks[taskNumber]); + System.out.println(" " + tasks.get(taskNumber)); + System.out.println(separator); + } catch (NumberFormatException e) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); + } + } + + private static void deleteTask(ArrayList tasks, String userInput) throws SparkleException { + try { + int taskNumber = Integer.parseInt(userInput) - 1; + if (taskNumber < 0 || taskNumber >= tasks.size()) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); + } + Task removedTask = tasks.remove(taskNumber); + System.out.print(separator); + System.out.println(" Noted. I've removed this task:"); + System.out.println(" " + removedTask); + System.out.println(" Now you have " + tasks.size() + " tasks in the list."); System.out.println(separator); } catch (NumberFormatException e) { throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); From 0db99f7a36a14ff4c439013aa24343d6e4961c8a Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 04:28:37 +0800 Subject: [PATCH 25/43] Add input to test delete function --- text-ui-test/input.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 5207e7b4e..101818c9a 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -11,5 +11,6 @@ list unmark 1 list add something +delete 3 list bye From 22b9dbff220b89408244c1429af5efb62b5d1307 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 05:50:37 +0800 Subject: [PATCH 26/43] Implement save function --- src/main/java/sparkle/core/Sparkle.java | 157 +++++++++++++----- .../sparkle/exception/SparkleException.java | 13 +- src/main/java/sparkle/task/Deadline.java | 20 +++ src/main/java/sparkle/task/Event.java | 20 +++ src/main/java/sparkle/task/Task.java | 24 ++- src/main/java/sparkle/task/Todo.java | 18 ++ text-ui-test/EXPECTED.TXT | 30 ++-- text-ui-test/data/sparkle.txt | 2 + text-ui-test/input.txt | 1 + 9 files changed, 214 insertions(+), 71 deletions(-) create mode 100644 text-ui-test/data/sparkle.txt diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index a45713618..73c4dee25 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -1,5 +1,12 @@ package sparkle.core; +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.List; import java.util.Scanner; import sparkle.exception.SparkleException; import sparkle.task.Deadline; @@ -9,7 +16,7 @@ public class Sparkle { - static String logo = + private static String logo = "NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN\n" + "NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN\n" + "NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN\n" @@ -47,18 +54,21 @@ public class Sparkle { + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; - static String separator = " ____________________________________________________________\n"; + private static final String FILE_PATH = "./data/sparkle.txt"; + private static final String DIRECTORY_PATH = "./data"; + private static final String SEPARATOR = + " ____________________________________________________________\n"; + private List tasks = new ArrayList<>(); public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - - System.out.println(separator + " Hey hey, I'm Sparkle!\n" + separator + "\n" + logo); + new Sparkle().run(); + } + private void run() { + Scanner scanner = new Scanner(System.in); + System.out.println(SEPARATOR + " Hey hey, I'm Sparkle!\n" + SEPARATOR + logo); System.out.println( - separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); - - Task[] tasks = new Task[100]; - int taskCount = 0; + SEPARATOR + " Got any cool, daring quests or risky biz? Just hit me up!\n" + SEPARATOR); while (true) { try { @@ -69,26 +79,28 @@ public static void main(String[] args) { switch (command) { case "bye": - System.out.print(separator); + System.out.print(SEPARATOR); System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); - System.out.println(separator); + System.out.println(SEPARATOR); scanner.close(); return; case "list": - printTaskList(tasks, taskCount); + printTaskList(); break; case "mark": case "unmark": - handleMarkTask(tasks, taskCount, details, command.equals("mark")); + handleMarkTask(details, command.equals("mark")); + saveTasks(); break; case "todo": if (details.isEmpty()) throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); - tasks[taskCount] = new Todo(details); - printAddedTask(tasks[taskCount++], taskCount); + tasks.add(new Todo(details)); + printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); + saveTasks(); break; case "deadline": @@ -98,9 +110,11 @@ public static void main(String[] args) { String[] deadlineParts = details.split(" /by ", 2); if (deadlineParts.length < 2) throw new SparkleException( - SparkleException.ErrorType.INVALID_FORMAT, "Deadline requires a /by time."); - tasks[taskCount] = new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim()); - printAddedTask(tasks[taskCount++], taskCount); + SparkleException.ErrorType.INVALID_FORMAT, + "Need a /by time! Or do you plan to finish it... never?"); + tasks.add(new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim())); + printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); + saveTasks(); break; case "event": @@ -110,71 +124,122 @@ public static void main(String[] args) { String[] eventParts = details.split(" /from ", 2); if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { throw new SparkleException( - SparkleException.ErrorType.INVALID_FORMAT, "Event requires /from and /to time."); + SparkleException.ErrorType.INVALID_FORMAT, + "Oops! You forgot the time slots! Gotta add both /from and /to, or this show" + + " ain't starting!"); } String[] timeParts = eventParts[1].split(" /to ", 2); - tasks[taskCount] = - new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim()); - printAddedTask(tasks[taskCount++], taskCount); + tasks.add(new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); + printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); + saveTasks(); + break; + + case "delete": + deleteTask(details); + saveTasks(); break; default: throw new SparkleException(SparkleException.ErrorType.UNKNOWN_COMMAND, command); } } catch (SparkleException e) { - printErrorMessage(e.getMessage()); + System.out.println(e.getMessage()); } } } - private static void printTaskList(Task[] tasks, int taskCount) { - System.out.print(separator); - if (taskCount == 0) { + private void printTaskList() { + System.out.print(SEPARATOR); + if (tasks.isEmpty()) { System.out.println(" Looks like there's nothing fun to mess with... How boring!"); } else { System.out.println(" Here are the tasks in your list~ "); - for (int i = 0; i < taskCount; i++) { - System.out.println(" " + (i + 1) + ". " + tasks[i]); + for (int i = 0; i < tasks.size(); i++) { + System.out.println(" " + (i + 1) + ". " + tasks.get(i)); } } - System.out.println(separator); + System.out.println(SEPARATOR); } - private static void handleMarkTask(Task[] tasks, int taskCount, String userInput, boolean isMark) - throws SparkleException { + private void handleMarkTask(String userInput, boolean isMark) throws SparkleException { try { int taskNumber = Integer.parseInt(userInput) - 1; - if (taskNumber < 0 || taskNumber >= taskCount) { + if (taskNumber < 0 || taskNumber >= tasks.size()) { throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } if (isMark) { - tasks[taskNumber].markAsDone(); - System.out.print(separator); - System.out.println(" Boom! Task's done and dusted~"); + tasks.get(taskNumber).markAsDone(); } else { - tasks[taskNumber].markAsUndone(); - System.out.print(separator); - System.out.println(" Not done yet, but it's still on the radar!"); + tasks.get(taskNumber).markAsUndone(); } - System.out.println(" " + tasks[taskNumber]); - System.out.println(separator); + System.out.print(SEPARATOR); + System.out.println(" Task tweaked! Hope it's more fun now~"); + System.out.println(" " + tasks.get(taskNumber)); + System.out.println(SEPARATOR); } catch (NumberFormatException e) { throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } } private static void printAddedTask(Task task, int taskCount) { - System.out.print(separator); + System.out.print(SEPARATOR); System.out.println(" Let's make it fun! I've added this task:"); System.out.println(" " + task); System.out.println( " Looks like you've got " + taskCount + " tasks in your list~ Better get moving!"); - System.out.println(separator); + System.out.println(SEPARATOR); } - private static void printErrorMessage(String message) { - System.out.print(separator); - System.out.println(" Whoops! " + message); - System.out.println(separator); + private void deleteTask(String userInput) throws SparkleException { + try { + int taskNumber = Integer.parseInt(userInput) - 1; + if (taskNumber < 0 || taskNumber >= tasks.size()) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); + } + Task removedTask = tasks.remove(taskNumber); + System.out.print(SEPARATOR); + System.out.println(" Noted. I've removed this task:"); + System.out.println(" " + removedTask); + System.out.println(" Now you have " + tasks.size() + " tasks in the list."); + System.out.println(SEPARATOR); + } catch (NumberFormatException e) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); + } + } + + private void saveTasks() { + try { + new File(DIRECTORY_PATH).mkdirs(); + BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH)); + for (Task task : tasks) { + writer.write(task.toFileFormat() + "\n"); + } + writer.close(); + } catch (IOException e) { + System.out.println(" Task list just went poof! Try saving again!s"); + } + } + + public static List loadFile() throws SparkleException { + List tasks = new ArrayList<>(); + File file = new File(FILE_PATH); + + if (!file.exists()) { + return tasks; + } + + try (Scanner scanner = new Scanner(file)) { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] parts = line.split(" \\| "); + tasks.add(Task.fromFileFormat(parts)); + } + } catch (FileNotFoundException e) { + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, + "That file's playing hide and seek… and winning!"); + } + + return tasks; } } diff --git a/src/main/java/sparkle/exception/SparkleException.java b/src/main/java/sparkle/exception/SparkleException.java index 1e49b1ff7..db6249a64 100644 --- a/src/main/java/sparkle/exception/SparkleException.java +++ b/src/main/java/sparkle/exception/SparkleException.java @@ -16,16 +16,19 @@ public SparkleException(ErrorType type, String details) { private static String generateMessage(ErrorType type, String details) { switch (type) { case EMPTY_TASK_DESCRIPTION: - return details + return " " + + details + " has nothing in the description!\n At least give me some fireworks to set off..."; case UNKNOWN_COMMAND: - return details + "? Huh? That's just noise!\n Say something that actually makes sense~"; + return " " + + details + + "? Huh? That's just noise!\n Say something that actually makes sense~"; case INVALID_TASK_NUMBER: - return "That task number's playing hide and seek~ Try again!"; + return " That task number's playing hide and seek~ Try again!"; case INVALID_FORMAT: - return details; + return " " + details; default: - return "A little chaos just slipped in—was that your plan?"; + return " A little chaos just slipped in—was that your plan?"; } } } diff --git a/src/main/java/sparkle/task/Deadline.java b/src/main/java/sparkle/task/Deadline.java index 25f495f8b..db5d705a7 100644 --- a/src/main/java/sparkle/task/Deadline.java +++ b/src/main/java/sparkle/task/Deadline.java @@ -1,5 +1,7 @@ package sparkle.task; +import sparkle.exception.SparkleException; + public class Deadline extends Task { protected String by; @@ -8,6 +10,24 @@ public Deadline(String description, String by) { this.by = by; } + public Deadline(String description, boolean isDone, String by) { + super(description, isDone); + this.by = by; + } + + @Override + public String toFileFormat() { + return "D | " + super.toFileFormat(); + } + + public static Deadline fromFileFormat(String[] parts) throws SparkleException { + if (parts.length < 4) { + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Deadline data"); + } + return new Deadline(parts[2], parts[1].equals("1"), parts[3]); + } + @Override public String toString() { return "[D]" + super.toString() + " (by: " + by + ")"; diff --git a/src/main/java/sparkle/task/Event.java b/src/main/java/sparkle/task/Event.java index 1b20de527..2f1090960 100644 --- a/src/main/java/sparkle/task/Event.java +++ b/src/main/java/sparkle/task/Event.java @@ -1,5 +1,7 @@ package sparkle.task; +import sparkle.exception.SparkleException; + public class Event extends Task { protected String from; protected String to; @@ -10,6 +12,24 @@ public Event(String description, String from, String to) { this.to = to; } + public Event(String description, boolean isDone, String from, String to) { + super(description, isDone); + this.from = from; + this.to = to; + } + + @Override + public String toFileFormat() { + return "E | " + super.toFileFormat(); + } + + public static Event fromFileFormat(String[] parts) throws SparkleException { + if (parts.length < 5) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Event data"); + } + return new Event(parts[2], parts[1].equals("1"), parts[3], parts[4]); + } + @Override public String toString() { return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; diff --git a/src/main/java/sparkle/task/Task.java b/src/main/java/sparkle/task/Task.java index daa55e849..9177fbeaa 100644 --- a/src/main/java/sparkle/task/Task.java +++ b/src/main/java/sparkle/task/Task.java @@ -1,5 +1,7 @@ package sparkle.task; +import sparkle.exception.SparkleException; + public class Task { protected String description; protected boolean isDone; @@ -9,8 +11,13 @@ public Task(String description) { this.isDone = false; } + public Task(String description, boolean isDone) { + this.description = description; + this.isDone = isDone; + } + public String getStatusIcon() { - return (isDone ? "X" : " "); // mark done task with X + return (isDone ? "X" : " "); } public void markAsDone() { @@ -21,6 +28,21 @@ public void markAsUndone() { this.isDone = false; } + public String toFileFormat() { + return (isDone ? "1" : "0") + " | " + description; + } + + public static Task fromFileFormat(String[] parts) throws SparkleException { + if (parts.length < 2) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Task data"); + } + + boolean isDone = parts[0].equals("1"); + String description = parts[1]; + + return new Task(description, isDone); + } + @Override public String toString() { return "[" + getStatusIcon() + "] " + description; diff --git a/src/main/java/sparkle/task/Todo.java b/src/main/java/sparkle/task/Todo.java index 1f3326c9e..9b3ff70ad 100644 --- a/src/main/java/sparkle/task/Todo.java +++ b/src/main/java/sparkle/task/Todo.java @@ -1,10 +1,28 @@ package sparkle.task; +import sparkle.exception.SparkleException; + public class Todo extends Task { public Todo(String description) { super(description); } + public Todo(String description, boolean isDone) { + super(description, isDone); + } + + @Override + public String toFileFormat() { + return "T | " + super.toFileFormat(); + } + + public static Todo fromFileFormat(String[] parts) throws SparkleException { + if (parts.length < 3) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Todo data"); + } + return new Todo(parts[2], parts[1].equals("1")); + } + @Override public String toString() { return "[T]" + super.toString(); diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 12c5497b4..e5b4b9840 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,6 @@ ____________________________________________________________ Hey hey, I'm Sparkle! ____________________________________________________________ - NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN @@ -54,21 +53,15 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN Looks like you've got 2 tasks in your list~ Better get moving! ____________________________________________________________ - ____________________________________________________________ - Whoops! Todo has nothing in the description! + Todo has nothing in the description! At least give me some fireworks to set off... - ____________________________________________________________ - ____________________________________________________________ Let's make it fun! I've added this task: [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) Looks like you've got 3 tasks in your list~ Better get moving! ____________________________________________________________ - ____________________________________________________________ - Whoops! Event requires /from and /to time. - ____________________________________________________________ - + Event requires /from and /to time. ____________________________________________________________ Here are the tasks in your list~ 1. [T][ ] Buy groceries @@ -77,19 +70,16 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Boom! Task's done and dusted~ + Task updated! [T][X] Buy groceries ____________________________________________________________ ____________________________________________________________ - Boom! Task's done and dusted~ + Task updated! [D][X] Submit assignment (by: 2025-02-20) ____________________________________________________________ - ____________________________________________________________ - Whoops! That task number's playing hide and seek~ Try again! - ____________________________________________________________ - + That task number's playing hide and seek~ Try again! ____________________________________________________________ Here are the tasks in your list~ 1. [T][X] Buy groceries @@ -98,7 +88,7 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Not done yet, but it's still on the radar! + Task updated! [T][ ] Buy groceries ____________________________________________________________ @@ -109,16 +99,18 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ - ____________________________________________________________ - Whoops! add? Huh? That's just noise! + add? Huh? That's just noise! Say something that actually makes sense~ ____________________________________________________________ + Noted. I've removed this task: + [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + Now you have 2 tasks in the list. + ____________________________________________________________ ____________________________________________________________ Here are the tasks in your list~ 1. [T][ ] Buy groceries 2. [D][X] Submit assignment (by: 2025-02-20) - 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ diff --git a/text-ui-test/data/sparkle.txt b/text-ui-test/data/sparkle.txt new file mode 100644 index 000000000..7667a8db8 --- /dev/null +++ b/text-ui-test/data/sparkle.txt @@ -0,0 +1,2 @@ +T | 0 | Buy groceries +D | 1 | Submit assignment diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 5207e7b4e..101818c9a 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -11,5 +11,6 @@ list unmark 1 list add something +delete 3 list bye From 1ecacb007a5b59a9ddda40d53ccd4d860b6c1f12 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 06:56:56 +0800 Subject: [PATCH 27/43] Implement function to read the file --- src/main/java/sparkle/core/Sparkle.java | 27 ++++++++++++++++-------- src/main/java/sparkle/task/Deadline.java | 2 +- src/main/java/sparkle/task/Event.java | 18 +--------------- src/main/java/sparkle/task/Task.java | 20 ++++++++++++------ 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index 8bc63a1a9..f2c1b3b94 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -71,6 +71,12 @@ private void run() { separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); ArrayList tasks = new ArrayList<>(); + try { + tasks = loadFile(); + System.out.println(" Tasks loaded successfully!"); + } catch (SparkleException e) { + System.out.println(" Failed to load tasks: " + e.getMessage()); + } while (true) { try { @@ -81,6 +87,7 @@ private void run() { switch (command) { case "bye": + saveTasks(); System.out.print(separator); System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); System.out.println(separator); @@ -140,7 +147,7 @@ private void run() { break; case "delete": - deleteTask(details); + deleteTask(tasks, details); saveTasks(); break; @@ -148,7 +155,9 @@ private void run() { throw new SparkleException(SparkleException.ErrorType.UNKNOWN_COMMAND, command); } } catch (SparkleException e) { + System.out.println(separator); System.out.println(e.getMessage()); + System.out.println(separator); } } } @@ -198,7 +207,7 @@ private static void printAddedTask(Task task, int taskCount) { System.out.println(separator); } - private void deleteTask(String userInput) throws SparkleException { + private static void deleteTask(ArrayList tasks, String userInput) throws SparkleException { try { int taskNumber = Integer.parseInt(userInput) - 1; if (taskNumber < 0 || taskNumber >= tasks.size()) { @@ -208,7 +217,7 @@ private void deleteTask(String userInput) throws SparkleException { System.out.print(separator); System.out.println(" Got it! Poof! This task is gone:"); System.out.println(" " + removedTask); - System.out.println(" Look at that! You’ve got " + tasks.size() + " tasks left to juggle!"); + System.out.println(" Look at that! You've got " + tasks.size() + " tasks left to juggle!"); System.out.println(separator); } catch (NumberFormatException e) { throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); @@ -228,26 +237,26 @@ private void saveTasks() { } } - public static List loadFile() throws SparkleException { - List tasks = new ArrayList<>(); + public static ArrayList loadFile() throws SparkleException { + ArrayList newtasks = new ArrayList<>(); File file = new File(FILE_PATH); if (!file.exists()) { - return tasks; + return newtasks; } try (Scanner scanner = new Scanner(file)) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); String[] parts = line.split(" \\| "); - tasks.add(Task.fromFileFormat(parts)); + newtasks.add(Task.fromFileFormat(parts)); } } catch (FileNotFoundException e) { throw new SparkleException( SparkleException.ErrorType.INVALID_FORMAT, "That file's playing hide and seek… and winning!"); } - - return tasks; + printTaskList(newtasks, newtasks.size()); + return newtasks; } } diff --git a/src/main/java/sparkle/task/Deadline.java b/src/main/java/sparkle/task/Deadline.java index db5d705a7..91ee06443 100644 --- a/src/main/java/sparkle/task/Deadline.java +++ b/src/main/java/sparkle/task/Deadline.java @@ -17,7 +17,7 @@ public Deadline(String description, boolean isDone, String by) { @Override public String toFileFormat() { - return "D | " + super.toFileFormat(); + return "D | " + super.toFileFormat() + " | " + by; } public static Deadline fromFileFormat(String[] parts) throws SparkleException { diff --git a/src/main/java/sparkle/task/Event.java b/src/main/java/sparkle/task/Event.java index 2f1090960..12a4cccc0 100644 --- a/src/main/java/sparkle/task/Event.java +++ b/src/main/java/sparkle/task/Event.java @@ -1,7 +1,5 @@ package sparkle.task; -import sparkle.exception.SparkleException; - public class Event extends Task { protected String from; protected String to; @@ -12,22 +10,8 @@ public Event(String description, String from, String to) { this.to = to; } - public Event(String description, boolean isDone, String from, String to) { - super(description, isDone); - this.from = from; - this.to = to; - } - - @Override public String toFileFormat() { - return "E | " + super.toFileFormat(); - } - - public static Event fromFileFormat(String[] parts) throws SparkleException { - if (parts.length < 5) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Event data"); - } - return new Event(parts[2], parts[1].equals("1"), parts[3], parts[4]); + return "E | " + super.toFileFormat() + " | " + from + "-" + to; } @Override diff --git a/src/main/java/sparkle/task/Task.java b/src/main/java/sparkle/task/Task.java index 9177fbeaa..80de38f2e 100644 --- a/src/main/java/sparkle/task/Task.java +++ b/src/main/java/sparkle/task/Task.java @@ -33,14 +33,20 @@ public String toFileFormat() { } public static Task fromFileFormat(String[] parts) throws SparkleException { - if (parts.length < 2) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Task data"); + char type = parts[0].charAt(0); + + switch (type) { + case 'T': + return Todo.fromFileFormat(parts); + case 'D': + return Deadline.fromFileFormat(parts); + case 'E': + return Event.fromFileFormat(parts); + default: + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, + "Oops! This task data's a mess—good luck fixing that!"); } - - boolean isDone = parts[0].equals("1"); - String description = parts[1]; - - return new Task(description, isDone); } @Override From 00c0d43da622e11c1c0cbf16ac773d275248be20 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 07:18:43 +0800 Subject: [PATCH 28/43] Fix error with reading file --- src/main/java/sparkle/core/Sparkle.java | 24 +++++++++--------- src/main/java/sparkle/task/Event.java | 20 +++++++++++++++ text-ui-test/EXPECTED.TXT | 33 ++++++++++++++++++++----- text-ui-test/data/sparkle.txt | 2 -- text-ui-test/runtest.sh | 5 +++- 5 files changed, 63 insertions(+), 21 deletions(-) delete mode 100644 text-ui-test/data/sparkle.txt diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index f2c1b3b94..ac2ade33f 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -6,7 +6,6 @@ import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; -import java.util.List; import java.util.Scanner; import sparkle.exception.SparkleException; import sparkle.task.Deadline; @@ -54,11 +53,12 @@ public class Sparkle { + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; - private static final String FILE_PATH = "./data/sparkle.txt"; - private static final String DIRECTORY_PATH = "./data"; + + private static final String FILE_PATH = "../data/sparkle.txt"; + private static final String DIRECTORY_PATH = "../data"; + private static final String separator = " ____________________________________________________________\n"; - private List tasks = new ArrayList<>(); public static void main(String[] args) { new Sparkle().run(); @@ -87,7 +87,7 @@ private void run() { switch (command) { case "bye": - saveTasks(); + saveTasks(tasks); System.out.print(separator); System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); System.out.println(separator); @@ -100,11 +100,11 @@ private void run() { case "mark": handleMarkTask(tasks, details, command.equals("mark")); - saveTasks(); + saveTasks(tasks); break; case "unmark": handleMarkTask(tasks, details, command.equals("mark")); - saveTasks(); + saveTasks(tasks); break; case "todo": @@ -112,7 +112,7 @@ private void run() { throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); tasks.add(new Todo(details)); printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); - saveTasks(); + saveTasks(tasks); break; case "deadline": @@ -126,7 +126,7 @@ private void run() { "Need a /by time! Or do you plan to finish it... never?"); tasks.add(new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim())); printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); - saveTasks(); + saveTasks(tasks); break; case "event": @@ -143,12 +143,12 @@ private void run() { String[] timeParts = eventParts[1].split(" /to ", 2); tasks.add(new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); - saveTasks(); + saveTasks(tasks); break; case "delete": deleteTask(tasks, details); - saveTasks(); + saveTasks(tasks); break; default: @@ -224,7 +224,7 @@ private static void deleteTask(ArrayList tasks, String userInput) throws S } } - private void saveTasks() { + private void saveTasks(ArrayList tasks) { try { new File(DIRECTORY_PATH).mkdirs(); BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH)); diff --git a/src/main/java/sparkle/task/Event.java b/src/main/java/sparkle/task/Event.java index 12a4cccc0..311da9813 100644 --- a/src/main/java/sparkle/task/Event.java +++ b/src/main/java/sparkle/task/Event.java @@ -1,5 +1,7 @@ package sparkle.task; +import sparkle.exception.SparkleException; + public class Event extends Task { protected String from; protected String to; @@ -10,6 +12,24 @@ public Event(String description, String from, String to) { this.to = to; } + public Event(String description, boolean isDone, String from, String to) { + super(description, isDone); + this.from = from; + this.to = to; + } + + public static Event fromFileFormat(String[] parts) throws SparkleException { + if (parts.length < 4) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Event data"); + } + String[] fromTo = parts[3].split("-", 2); + if (fromTo.length < 2) { + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, "Invalid Event time format"); + } + return new Event(parts[2], parts[1].equals("1"), fromTo[0], fromTo[1]); + } + public String toFileFormat() { return "E | " + super.toFileFormat() + " | " + from + "-" + to; } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index e5b4b9840..d55f24d7f 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -41,6 +41,11 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN Got any cool, daring quests or risky biz? Just hit me up! ____________________________________________________________ + ____________________________________________________________ + Looks like there's nothing fun to mess with... How boring! + ____________________________________________________________ + + Tasks loaded successfully! ____________________________________________________________ Let's make it fun! I've added this task: [T][ ] Buy groceries @@ -53,15 +58,23 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN Looks like you've got 2 tasks in your list~ Better get moving! ____________________________________________________________ + ____________________________________________________________ + Todo has nothing in the description! At least give me some fireworks to set off... + ____________________________________________________________ + ____________________________________________________________ Let's make it fun! I've added this task: [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) Looks like you've got 3 tasks in your list~ Better get moving! ____________________________________________________________ - Event requires /from and /to time. + ____________________________________________________________ + + Oops! You forgot the time slots! Gotta add both /from and /to, or this show ain't starting! + ____________________________________________________________ + ____________________________________________________________ Here are the tasks in your list~ 1. [T][ ] Buy groceries @@ -70,16 +83,20 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Task updated! + Boom! Task's done and dusted~ [T][X] Buy groceries ____________________________________________________________ ____________________________________________________________ - Task updated! + Boom! Task's done and dusted~ [D][X] Submit assignment (by: 2025-02-20) ____________________________________________________________ + ____________________________________________________________ + That task number's playing hide and seek~ Try again! + ____________________________________________________________ + ____________________________________________________________ Here are the tasks in your list~ 1. [T][X] Buy groceries @@ -88,7 +105,7 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Task updated! + Not done yet, but it's still on the radar! [T][ ] Buy groceries ____________________________________________________________ @@ -99,12 +116,16 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ + ____________________________________________________________ + add? Huh? That's just noise! Say something that actually makes sense~ ____________________________________________________________ - Noted. I've removed this task: + + ____________________________________________________________ + Got it! Poof! This task is gone: [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) - Now you have 2 tasks in the list. + Look at that! You've got 2 tasks left to juggle! ____________________________________________________________ ____________________________________________________________ diff --git a/text-ui-test/data/sparkle.txt b/text-ui-test/data/sparkle.txt deleted file mode 100644 index 7667a8db8..000000000 --- a/text-ui-test/data/sparkle.txt +++ /dev/null @@ -1,2 +0,0 @@ -T | 0 | Buy groceries -D | 1 | Submit assignment diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index 177de7c0b..ae17eb484 100755 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +# Move to the script directory (text-ui-test/) +cd "$(dirname "$0")" || exit 1 + # create bin directory if it doesn't exist if [ ! -d "../bin" ] then @@ -35,4 +38,4 @@ then else echo "Test result: FAILED" exit 1 -fi \ No newline at end of file +fi From 2b37b332831dc4187e1b91c91bdfb1fb4a09419c Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 07:43:16 +0800 Subject: [PATCH 29/43] Import Gradle for jar file --- build.gradle | 19 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 251 +++++++++++++++++++++++ gradlew.bat | 94 +++++++++ 5 files changed, 371 insertions(+) create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..2ce348a61 --- /dev/null +++ b/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' + id 'application' + id 'com.github.johnrengelman.shadow' version '7.1.2' +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + +application { + mainClass = "sparkle.core.Sparkle" +} + +shadowJar { + archiveFileName = 'sparkle.jar' +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..a4b76b9530d66f5e68d973ea569d8e19de379189 GIT binary patch literal 43583 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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 GZ~q4|mN%#X literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..e18bc253b --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 000000000..f3b75f3b0 --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..9b42019c7 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From 8d977dff0508f7ececfcc27cfd3ea71c0073a244 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 07:46:26 +0800 Subject: [PATCH 30/43] Fix spacing and message --- src/main/java/sparkle/core/Sparkle.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index ac2ade33f..329f0ce27 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -73,10 +73,12 @@ private void run() { ArrayList tasks = new ArrayList<>(); try { tasks = loadFile(); - System.out.println(" Tasks loaded successfully!"); + System.out.println(" Look at that! Your tasks made it back in one piece—miraculous!"); } catch (SparkleException e) { - System.out.println(" Failed to load tasks: " + e.getMessage()); + System.out.println(" Your tasks took a wrong turn and got lost...Tragic!"); + System.out.println(e.getMessage()); } + System.out.println(separator); while (true) { try { From 198bc8ce4850dc3bef04955da4ccea3638954e55 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 07:49:52 +0800 Subject: [PATCH 31/43] Remove unnecessary statement --- src/main/java/sparkle/core/Sparkle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index 329f0ce27..04ab92638 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -71,6 +71,7 @@ private void run() { separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); ArrayList tasks = new ArrayList<>(); + try { tasks = loadFile(); System.out.println(" Look at that! Your tasks made it back in one piece—miraculous!"); @@ -258,7 +259,6 @@ public static ArrayList loadFile() throws SparkleException { SparkleException.ErrorType.INVALID_FORMAT, "That file's playing hide and seek… and winning!"); } - printTaskList(newtasks, newtasks.size()); return newtasks; } } From 43f123e1ab6f99e5caee317dc6b691a09ac4e427 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 21 Feb 2025 15:23:18 +0800 Subject: [PATCH 32/43] Fix filepath --- src/main/java/sparkle/core/Sparkle.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index 04ab92638..a2f0503cb 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -54,8 +54,8 @@ public class Sparkle { + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; - private static final String FILE_PATH = "../data/sparkle.txt"; - private static final String DIRECTORY_PATH = "../data"; + private static final String FILE_PATH = "./data/sparkle.txt"; + private static final String DIRECTORY_PATH = "./data"; private static final String separator = " ____________________________________________________________\n"; From b63c4f38bc5fadb9670fbf15045439177b46713a Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 10:54:28 +0800 Subject: [PATCH 33/43] OOP implementation --- src/main/java/sparkle/core/Parser.java | 11 + src/main/java/sparkle/core/Sparkle.java | 306 +++++------------------ src/main/java/sparkle/core/Storage.java | 47 ++++ src/main/java/sparkle/core/TaskList.java | 52 ++++ src/main/java/sparkle/core/Ui.java | 96 +++++++ test_jar/sparkle.jar | Bin 0 -> 13778 bytes 6 files changed, 262 insertions(+), 250 deletions(-) create mode 100644 src/main/java/sparkle/core/Parser.java create mode 100644 src/main/java/sparkle/core/Storage.java create mode 100644 src/main/java/sparkle/core/TaskList.java create mode 100644 src/main/java/sparkle/core/Ui.java create mode 100644 test_jar/sparkle.jar diff --git a/src/main/java/sparkle/core/Parser.java b/src/main/java/sparkle/core/Parser.java new file mode 100644 index 000000000..b445d99a0 --- /dev/null +++ b/src/main/java/sparkle/core/Parser.java @@ -0,0 +1,11 @@ +package sparkle.core; + +public class Parser { + + public static String[] parse(String userInput) { + String[] commandParts = userInput.split(" ", 2); + String command = commandParts[0].toLowerCase(); + String details = commandParts.length > 1 ? commandParts[1].trim() : ""; + return new String[]{command, details}; + } +} diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index a2f0503cb..eadd20c73 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -1,264 +1,70 @@ package sparkle.core; -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.Scanner; -import sparkle.exception.SparkleException; -import sparkle.task.Deadline; -import sparkle.task.Event; import sparkle.task.Task; -import sparkle.task.Todo; - -public class Sparkle { - - private static String logo = - "NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN\n" - + "NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN\n" - + "NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN\n" - + "NHZOvz1>>>>>;>;jHMMHHMMHHngHHbkWMMHH@MMMb .dHMs?WmaJJHpHWWMNZzOUUWHHHggkM\n" - + "#Hz>>>>>;>>;;;(MMNqkkkkqHHHHWHHH@@@@MMMM@N. d@MI<~(?>`` ?WHHHN<;<(JHHd@KzM\n" - + "#Hz>;;;<::~~<:~~~:~JMgHppWWWY(dM@MHHH@@MMMHM@@@@N-<(v7<-__ `.-~_(dHkWbpbbbbSM\n" - + "NH>~~:~~~(MmHWWY=(WWHM#XXMH@@H@@@@@@g@@Nv! (61j.~dWWHgHHWWKM\n" - + "#K>~~_jY.(HHWXM@@Mggg@HHgB&HgmgHmmkwXNSWHHWvWYTk-..______~~JMHHggggqHM\n" - + "NK!_..%._(kHWM@@MgmggHH9! (HMHHqqqqgHHHHWHHkUkU9>~~~~~~~~~~(MWHHgggkWM\n" - + "NK_...~.-dHdM@MMgmmgHHm...J0kWHkppkHmHHkHHUKHWm.......-((-_(HNVWHmgHSM\n" - + "NH<...~-JWMHMHHggqgHHYUMMHHwHWHpffppHWpbbbod@g@@M@@@HHMWNmazuHffpHMHXM\n" - + "#HJM@gH:?-``````` `_` `` .! __?~(HgHHkqqkkqHkXfppWHMMMh-jM\n" - + "#HHgmKMHpHHWI;_ jc;;<1d$-.dHHqH$ ``` JY-JWXWVfffWkUUWMMRM\n" - + "NHGdCldgHSXHkWXHR `````jk1<_(jr``.V!?WHH9Y>`` .``` .dpqWbHkWfudkHqTAwM\n" - + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" - + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" - + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; - - private static final String FILE_PATH = "./data/sparkle.txt"; - private static final String DIRECTORY_PATH = "./data"; - - private static final String separator = - " ____________________________________________________________\n"; - - public static void main(String[] args) { - new Sparkle().run(); - } +import sparkle.exception.SparkleException; - private void run() { - Scanner scanner = new Scanner(System.in); - System.out.println(separator + " Hey hey, I'm Sparkle!\n" + separator + logo); - System.out.println( - separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); +import java.util.Scanner; - ArrayList tasks = new ArrayList<>(); +public class Sparkle { - try { - tasks = loadFile(); - System.out.println(" Look at that! Your tasks made it back in one piece—miraculous!"); - } catch (SparkleException e) { - System.out.println(" Your tasks took a wrong turn and got lost...Tragic!"); - System.out.println(e.getMessage()); + private Ui ui; + private Storage storage; + private TaskList tasks; + + public Sparkle(String filePath) { + ui = new Ui(); + storage = new Storage(); + try { + tasks = new TaskList(storage.load()); + } catch (SparkleException e) { + ui.showLoadingError(); + tasks = new TaskList(); + } } - System.out.println(separator); - - while (true) { - try { - String userInput = scanner.nextLine().trim(); - String[] commandParts = userInput.split(" ", 2); - String command = commandParts[0].toLowerCase(); - String details = commandParts.length > 1 ? commandParts[1].trim() : ""; - - switch (command) { - case "bye": - saveTasks(tasks); - System.out.print(separator); - System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); - System.out.println(separator); - scanner.close(); - return; - - case "list": - printTaskList(tasks, tasks.size()); - break; - - case "mark": - handleMarkTask(tasks, details, command.equals("mark")); - saveTasks(tasks); - break; - case "unmark": - handleMarkTask(tasks, details, command.equals("mark")); - saveTasks(tasks); - break; - case "todo": - if (details.isEmpty()) - throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); - tasks.add(new Todo(details)); - printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); - saveTasks(tasks); - break; - - case "deadline": - if (details.isEmpty()) - throw new SparkleException( - SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Deadline"); - String[] deadlineParts = details.split(" /by ", 2); - if (deadlineParts.length < 2) - throw new SparkleException( - SparkleException.ErrorType.INVALID_FORMAT, - "Need a /by time! Or do you plan to finish it... never?"); - tasks.add(new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim())); - printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); - saveTasks(tasks); - break; - - case "event": - if (details.isEmpty()) - throw new SparkleException( - SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Event"); - String[] eventParts = details.split(" /from ", 2); - if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { - throw new SparkleException( - SparkleException.ErrorType.INVALID_FORMAT, - "Oops! You forgot the time slots! Gotta add both /from and /to, or this show" - + " ain't starting!"); + public void run() { + ui.showLogo(); + ui.showGreeting(); + + try (Scanner scanner = new Scanner(System.in)) { + while (true) { + String userInput = scanner.nextLine().trim(); + String[] commandParts = Parser.parse(userInput); + String command = commandParts[0]; + String details = commandParts[1]; + + try { + switch (command) { + case "bye": + storage.save(tasks.getTasks()); + ui.showExitMessage(); + return; + case "list": + ui.showTaskList(tasks.getTasks(), tasks.size()); + break; + case "mark": + tasks.markTaskAsDone(Integer.parseInt(details) - 1); + ui.showTaskList(tasks.getTasks(), tasks.size()); + break; + case "unmark": + tasks.markTaskAsUndone(Integer.parseInt(details) - 1); + ui.showTaskList(tasks.getTasks(), tasks.size()); + break; + case "todo": + tasks.addTask(new Task(details)); + ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); + break; + default: + throw new SparkleException(SparkleException.ErrorType.UNKNOWN_COMMAND, command); + } + } catch (SparkleException e) { + ui.showError(e); + } } - String[] timeParts = eventParts[1].split(" /to ", 2); - tasks.add(new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); - printAddedTask(tasks.get(tasks.size() - 1), tasks.size()); - saveTasks(tasks); - break; - - case "delete": - deleteTask(tasks, details); - saveTasks(tasks); - break; - - default: - throw new SparkleException(SparkleException.ErrorType.UNKNOWN_COMMAND, command); } - } catch (SparkleException e) { - System.out.println(separator); - System.out.println(e.getMessage()); - System.out.println(separator); - } - } - } - - private static void printTaskList(ArrayList tasks, int taskCount) { - System.out.print(separator); - if (taskCount == 0) { - System.out.println(" Looks like there's nothing fun to mess with... How boring!"); - } else { - System.out.println(" Here are the tasks in your list~ "); - for (int i = 0; i < tasks.size(); i++) { - System.out.println(" " + (i + 1) + ". " + tasks.get(i)); - } - } - System.out.println(separator); - } - - private static void handleMarkTask(ArrayList tasks, String userInput, boolean isMark) - throws SparkleException { - try { - int taskNumber = Integer.parseInt(userInput) - 1; - if (taskNumber < 0 || taskNumber >= tasks.size()) { - throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); - } - if (isMark) { - tasks.get(taskNumber).markAsDone(); - System.out.print(separator); - System.out.println(" Boom! Task's done and dusted~"); - } else { - tasks.get(taskNumber).markAsUndone(); - System.out.print(separator); - System.out.println(" Not done yet, but it's still on the radar!"); - } - System.out.println(" " + tasks.get(taskNumber)); - System.out.println(separator); - } catch (NumberFormatException e) { - throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); - } - } - - private static void printAddedTask(Task task, int taskCount) { - System.out.print(separator); - System.out.println(" Let's make it fun! I've added this task:"); - System.out.println(" " + task); - System.out.println( - " Looks like you've got " + taskCount + " tasks in your list~ Better get moving!"); - System.out.println(separator); - } - - private static void deleteTask(ArrayList tasks, String userInput) throws SparkleException { - try { - int taskNumber = Integer.parseInt(userInput) - 1; - if (taskNumber < 0 || taskNumber >= tasks.size()) { - throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); - } - Task removedTask = tasks.remove(taskNumber); - System.out.print(separator); - System.out.println(" Got it! Poof! This task is gone:"); - System.out.println(" " + removedTask); - System.out.println(" Look at that! You've got " + tasks.size() + " tasks left to juggle!"); - System.out.println(separator); - } catch (NumberFormatException e) { - throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); - } - } - - private void saveTasks(ArrayList tasks) { - try { - new File(DIRECTORY_PATH).mkdirs(); - BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH)); - for (Task task : tasks) { - writer.write(task.toFileFormat() + "\n"); - } - writer.close(); - } catch (IOException e) { - System.out.println(" Task list just went poof! Try saving again!s"); - } - } - - public static ArrayList loadFile() throws SparkleException { - ArrayList newtasks = new ArrayList<>(); - File file = new File(FILE_PATH); - - if (!file.exists()) { - return newtasks; } - try (Scanner scanner = new Scanner(file)) { - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - String[] parts = line.split(" \\| "); - newtasks.add(Task.fromFileFormat(parts)); - } - } catch (FileNotFoundException e) { - throw new SparkleException( - SparkleException.ErrorType.INVALID_FORMAT, - "That file's playing hide and seek… and winning!"); + public static void main(String[] args) { + new Sparkle("data/sparkle.txt").run(); } - return newtasks; - } } diff --git a/src/main/java/sparkle/core/Storage.java b/src/main/java/sparkle/core/Storage.java new file mode 100644 index 000000000..9dce794ba --- /dev/null +++ b/src/main/java/sparkle/core/Storage.java @@ -0,0 +1,47 @@ +package sparkle.core; + +import sparkle.exception.SparkleException; +import sparkle.task.Task; + +import java.io.*; +import java.util.ArrayList; +import java.util.Scanner; + +public class Storage { + + private static final String FILE_PATH = "./data/sparkle.txt"; + private static final String DIRECTORY_PATH = "./data"; + + public ArrayList load() throws SparkleException { + ArrayList newtasks = new ArrayList<>(); + File file = new File(FILE_PATH); + + if (!file.exists()) { + return newtasks; + } + + try (Scanner scanner = new Scanner(file)) { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] parts = line.split(" \\| "); + newtasks.add(Task.fromFileFormat(parts)); + } + } catch (FileNotFoundException e) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "That file's playing hide and seek… and winning!"); + } + return newtasks; + } + + public void save(ArrayList tasks) { + try { + new File(DIRECTORY_PATH).mkdirs(); + BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH)); + for (Task task : tasks) { + writer.write(task.toFileFormat() + "\n"); + } + writer.close(); + } catch (IOException e) { + System.out.println(" Task list just went poof! Try saving again!"); + } + } +} diff --git a/src/main/java/sparkle/core/TaskList.java b/src/main/java/sparkle/core/TaskList.java new file mode 100644 index 000000000..3a77a8798 --- /dev/null +++ b/src/main/java/sparkle/core/TaskList.java @@ -0,0 +1,52 @@ +package sparkle.core; + +import sparkle.exception.SparkleException; +import java.util.ArrayList; +import sparkle.task.Task; + + +public class TaskList { + + private ArrayList tasks; + + public TaskList() { + tasks = new ArrayList<>(); + } + + public TaskList(ArrayList tasks) { + this.tasks = tasks; + } + + public void addTask(Task task) { + tasks.add(task); + } + + public void deleteTask(int taskNumber) throws SparkleException { + if (taskNumber < 0 || taskNumber >= tasks.size()) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); + } + tasks.remove(taskNumber); + } + + public void markTaskAsDone(int taskNumber) throws SparkleException { + if (taskNumber < 0 || taskNumber >= tasks.size()) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); + } + tasks.get(taskNumber).markAsDone(); + } + + public void markTaskAsUndone(int taskNumber) throws SparkleException { + if (taskNumber < 0 || taskNumber >= tasks.size()) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); + } + tasks.get(taskNumber).markAsUndone(); + } + + public ArrayList getTasks() { + return tasks; + } + + public int size() { + return tasks.size(); + } +} diff --git a/src/main/java/sparkle/core/Ui.java b/src/main/java/sparkle/core/Ui.java new file mode 100644 index 000000000..da052e8b4 --- /dev/null +++ b/src/main/java/sparkle/core/Ui.java @@ -0,0 +1,96 @@ +package sparkle.core; + +import sparkle.task.Task; +import sparkle.exception.SparkleException; +import java.util.ArrayList; + + +public class Ui { + + private static final String separator = + " ____________________________________________________________\n"; + private static String logo = + "NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN\n" + + "NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN\n" + + "NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN\n" + + "NHZOvz1>>>>>;>;jHMMHHMMHHngHHbkWMMHH@MMMb .dHMs?WmaJJHpHWWMNZzOUUWHHHggkM\n" + + "#Hz>>>>>;>>;;;(MMNqkkkkqHHHHWHHH@@@@MMMM@N. d@MI<~(?>`` ?WHHHN<;<(JHHd@KzM\n" + + "#Hz>;;;<::~~<:~~~:~JMgHppWWWY(dM@MHHH@@MMMHM@@@@N-<(v7<-__ `.-~_(dHkWbpbbbbSM\n" + + "NH>~~:~~~(MmHWWY=(WWHM#XXMH@@H@@@@@@g@@Nv! (61j.~dWWHgHHWWKM\n" + + "#K>~~_jY.(HHWXM@@Mggg@HHgB&HgmgHmmkwXNSWHHWvWYTk-..______~~JMHHggggqHM\n" + + "NK!_..%._(kHWM@@MgmggHH9! (HMHHqqqqgHHHHWHHkUkU9>~~~~~~~~~~(MWHHgggkWM\n" + + "NK_...~.-dHdM@MMgmmgHHm...J0kWHkppkHmHHkHHUKHWm.......-((-_(HNVWHmgHSM\n" + + "NH<...~-JWMHMHHggqgHHYUMMHHwHWHpffppHWpbbbod@g@@M@@@HHMWNmazuHffpHMHXM\n" + + "#HJM@gH:?-``````` `_` `` .! __?~(HgHHkqqkkqHkXfppWHMMMh-jM\n" + + "#HHgmKMHpHHWI;_ jc;;<1d$-.dHHqH$ ``` JY-JWXWVfffWkUUWMMRM\n" + + "NHGdCldgHSXHkWXHR `````jk1<_(jr``.V!?WHH9Y>`` .``` .dpqWbHkWfudkHqTAwM\n" + + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" + + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" + + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; + + public void showLogo() { + + System.out.println(separator + " Hey hey, I'm Sparkle!\n" + separator + logo); + } + + public void showGreeting() { + System.out.println(separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); + } + + public void showTaskList(ArrayList tasks, int taskCount) { + System.out.print(separator); + if (taskCount == 0) { + System.out.println(" Looks like there's nothing fun to mess with... How boring!"); + } else { + System.out.println(" Here are the tasks in your list~ "); + for (int i = 0; i < tasks.size(); i++) { + System.out.println(" " + (i + 1) + ". " + tasks.get(i)); + } + } + System.out.println(separator); + } + + public void showTaskAdded(Task task, int taskCount) { + System.out.print(separator); + System.out.println(" Let's make it fun! I've added this task:"); + System.out.println(" " + task); + System.out.println(" Looks like you've got " + taskCount + " tasks in your list~ Better get moving!"); + System.out.println(separator); + } + + public void showError(SparkleException e) { + System.out.println(separator); + System.out.println(e.getMessage()); + System.out.println(separator); + } + + public void showExitMessage() { + System.out.print(separator); + System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); + System.out.println(separator); + } + + public void showLoadingError() { + System.out.println(" Your tasks took a wrong turn and got lost...Tragic!"); + } +} diff --git a/test_jar/sparkle.jar b/test_jar/sparkle.jar new file mode 100644 index 0000000000000000000000000000000000000000..423d11908c12e713c9b472ff1b9b7f59735f62e3 GIT binary patch literal 13778 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�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 literal 0 HcmV?d00001 From 89f97c338c2e8fb90d62d2f9483d2c02e313dffe Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 14:00:07 +0800 Subject: [PATCH 34/43] Fixed bug in OOP change --- src/main/java/sparkle/core/Sparkle.java | 146 +++++++++++++++-------- src/main/java/sparkle/core/TaskList.java | 5 +- src/main/java/sparkle/core/Ui.java | 115 +++++++++++------- test_jar/sparkle.jar | Bin 13778 -> 16975 bytes text-ui-test/input.txt | 1 + 5 files changed, 168 insertions(+), 99 deletions(-) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index eadd20c73..5be50285e 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -1,70 +1,112 @@ package sparkle.core; +import sparkle.task.Deadline; +import sparkle.task.Event; import sparkle.task.Task; +import sparkle.task.Todo; import sparkle.exception.SparkleException; import java.util.Scanner; public class Sparkle { - private Ui ui; - private Storage storage; - private TaskList tasks; + private Ui ui; + private Storage storage; + private TaskList tasks; - public Sparkle(String filePath) { - ui = new Ui(); - storage = new Storage(); - try { - tasks = new TaskList(storage.load()); - } catch (SparkleException e) { - ui.showLoadingError(); - tasks = new TaskList(); - } + public Sparkle(String filePath) { + ui = new Ui(); + storage = new Storage(); + try { + tasks = new TaskList(storage.load()); + ui.showLoadingSuccess(); + } catch (SparkleException e) { + ui.showLoadingError(); + System.out.println(" Failed to load tasks: " + e.getMessage()); + tasks = new TaskList(); } + } + + public void run() { + ui.showLogo(); + ui.showGreeting(); - public void run() { - ui.showLogo(); - ui.showGreeting(); + Scanner scanner = new Scanner(System.in); - try (Scanner scanner = new Scanner(System.in)) { - while (true) { - String userInput = scanner.nextLine().trim(); - String[] commandParts = Parser.parse(userInput); - String command = commandParts[0]; - String details = commandParts[1]; + try { + while (true) { + String userInput = scanner.nextLine().trim(); + String[] commandParts = Parser.parse(userInput); + String command = commandParts[0]; + String details = commandParts[1]; - try { - switch (command) { - case "bye": - storage.save(tasks.getTasks()); - ui.showExitMessage(); - return; - case "list": - ui.showTaskList(tasks.getTasks(), tasks.size()); - break; - case "mark": - tasks.markTaskAsDone(Integer.parseInt(details) - 1); - ui.showTaskList(tasks.getTasks(), tasks.size()); - break; - case "unmark": - tasks.markTaskAsUndone(Integer.parseInt(details) - 1); - ui.showTaskList(tasks.getTasks(), tasks.size()); - break; - case "todo": - tasks.addTask(new Task(details)); - ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); - break; - default: - throw new SparkleException(SparkleException.ErrorType.UNKNOWN_COMMAND, command); - } - } catch (SparkleException e) { - ui.showError(e); - } - } + try { + switch (command) { + case "bye": + storage.save(tasks.getTasks()); + ui.showExitMessage(); + return; + case "list": + ui.showTaskList(tasks.getTasks(), tasks.size()); + break; + case "mark": + tasks.markTaskAsDone(Integer.parseInt(details) - 1); + ui.showMarkTaskDone(tasks.getTasks().get(Integer.parseInt(details) - 1)); + break; + case "unmark": + tasks.markTaskAsUndone(Integer.parseInt(details) - 1); + ui.showMarkTaskUndone(tasks.getTasks().get(Integer.parseInt(details) - 1)); + break; + case "todo": + if (details.isEmpty()) { + throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); + } + tasks.addTask(new Todo(details)); + ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); + break; + case "deadline": + if (details.isEmpty()) { + throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, ""); + } + String[] deadlineParts = details.split(" /by ", 2); + if (deadlineParts.length < 2) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, + "Need a /by time! Or do you plan to finish it... never?"); + } + tasks.addTask(new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim())); + ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); + break; + case "event": + if (details.isEmpty()) { + throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Event"); + } + String[] eventParts = details.split(" /from ", 2); + if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, + "Oops! You forgot the time slots! Gotta add both /from and /to, or this show ain't starting!"); + } + String[] timeParts = eventParts[1].split(" /to ", 2); + tasks.addTask(new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); + ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); + break; + case "delete": + int taskToDelete = Integer.parseInt(details) - 1; + Task removedTask = tasks.deleteTask(taskToDelete); + ui.showTaskDeleted(removedTask, tasks.size()); + break; + default: + throw new SparkleException(SparkleException.ErrorType.UNKNOWN_COMMAND, command); + } + } catch (SparkleException e) { + ui.showError(e); } + } + } finally { + scanner.close(); } + } - public static void main(String[] args) { - new Sparkle("data/sparkle.txt").run(); - } + public static void main(String[] args) { + new Sparkle("data/sparkle.txt").run(); + } } diff --git a/src/main/java/sparkle/core/TaskList.java b/src/main/java/sparkle/core/TaskList.java index 3a77a8798..efcb21d3a 100644 --- a/src/main/java/sparkle/core/TaskList.java +++ b/src/main/java/sparkle/core/TaskList.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import sparkle.task.Task; - public class TaskList { private ArrayList tasks; @@ -21,11 +20,13 @@ public void addTask(Task task) { tasks.add(task); } - public void deleteTask(int taskNumber) throws SparkleException { + public Task deleteTask(int taskNumber) throws SparkleException { if (taskNumber < 0 || taskNumber >= tasks.size()) { throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } + Task deleteTask = tasks.get(taskNumber); tasks.remove(taskNumber); + return deleteTask; } public void markTaskAsDone(int taskNumber) throws SparkleException { diff --git a/src/main/java/sparkle/core/Ui.java b/src/main/java/sparkle/core/Ui.java index da052e8b4..0fb42cb9b 100644 --- a/src/main/java/sparkle/core/Ui.java +++ b/src/main/java/sparkle/core/Ui.java @@ -4,52 +4,49 @@ import sparkle.exception.SparkleException; import java.util.ArrayList; - public class Ui { - private static final String separator = - " ____________________________________________________________\n"; - private static String logo = - "NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN\n" - + "NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN\n" - + "NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN\n" - + "NHZOvz1>>>>>;>;jHMMHHMMHHngHHbkWMMHH@MMMb .dHMs?WmaJJHpHWWMNZzOUUWHHHggkM\n" - + "#Hz>>>>>;>>;;;(MMNqkkkkqHHHHWHHH@@@@MMMM@N. d@MI<~(?>`` ?WHHHN<;<(JHHd@KzM\n" - + "#Hz>;;;<::~~<:~~~:~JMgHppWWWY(dM@MHHH@@MMMHM@@@@N-<(v7<-__ `.-~_(dHkWbpbbbbSM\n" - + "NH>~~:~~~(MmHWWY=(WWHM#XXMH@@H@@@@@@g@@Nv! (61j.~dWWHgHHWWKM\n" - + "#K>~~_jY.(HHWXM@@Mggg@HHgB&HgmgHmmkwXNSWHHWvWYTk-..______~~JMHHggggqHM\n" - + "NK!_..%._(kHWM@@MgmggHH9! (HMHHqqqqgHHHHWHHkUkU9>~~~~~~~~~~(MWHHgggkWM\n" - + "NK_...~.-dHdM@MMgmmgHHm...J0kWHkppkHmHHkHHUKHWm.......-((-_(HNVWHmgHSM\n" - + "NH<...~-JWMHMHHggqgHHYUMMHHwHWHpffppHWpbbbod@g@@M@@@HHMWNmazuHffpHMHXM\n" - + "#HJM@gH:?-``````` `_` `` .! __?~(HgHHkqqkkqHkXfppWHMMMh-jM\n" - + "#HHgmKMHpHHWI;_ jc;;<1d$-.dHHqH$ ``` JY-JWXWVfffWkUUWMMRM\n" - + "NHGdCldgHSXHkWXHR `````jk1<_(jr``.V!?WHH9Y>`` .``` .dpqWbHkWfudkHqTAwM\n" - + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" - + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" - + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; + private static final String separator = " ____________________________________________________________\n"; + private static String logo = "NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN\n" + + "NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN\n" + + "NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN\n" + + "NHZOvz1>>>>>;>;jHMMHHMMHHngHHbkWMMHH@MMMb .dHMs?WmaJJHpHWWMNZzOUUWHHHggkM\n" + + "#Hz>>>>>;>>;;;(MMNqkkkkqHHHHWHHH@@@@MMMM@N. d@MI<~(?>`` ?WHHHN<;<(JHHd@KzM\n" + + "#Hz>;;;<::~~<:~~~:~JMgHppWWWY(dM@MHHH@@MMMHM@@@@N-<(v7<-__ `.-~_(dHkWbpbbbbSM\n" + + "NH>~~:~~~(MmHWWY=(WWHM#XXMH@@H@@@@@@g@@Nv! (61j.~dWWHgHHWWKM\n" + + "#K>~~_jY.(HHWXM@@Mggg@HHgB&HgmgHmmkwXNSWHHWvWYTk-..______~~JMHHggggqHM\n" + + "NK!_..%._(kHWM@@MgmggHH9! (HMHHqqqqgHHHHWHHkUkU9>~~~~~~~~~~(MWHHgggkWM\n" + + "NK_...~.-dHdM@MMgmmgHHm...J0kWHkppkHmHHkHHUKHWm.......-((-_(HNVWHmgHSM\n" + + "NH<...~-JWMHMHHggqgHHYUMMHHwHWHpffppHWpbbbod@g@@M@@@HHMWNmazuHffpHMHXM\n" + + "#HJM@gH:?-``````` `_` `` .! __?~(HgHHkqqkkqHkXfppWHMMMh-jM\n" + + "#HHgmKMHpHHWI;_ jc;;<1d$-.dHHqH$ ``` JY-JWXWVfffWkUUWMMRM\n" + + "NHGdCldgHSXHkWXHR `````jk1<_(jr``.V!?WHH9Y>`` .``` .dpqWbHkWfudkHqTAwM\n" + + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" + + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" + + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; public void showLogo() { - + System.out.println(separator + " Hey hey, I'm Sparkle!\n" + separator + logo); } @@ -57,6 +54,15 @@ public void showGreeting() { System.out.println(separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); } + public void showLoadingSuccess() { + System.out.println( + separator + " Look at that! Your tasks made it back in one piece—miraculous!\n" + separator); + } + + public void showLoadingError() { + System.out.println(separator + " Your tasks took a wrong turn and got lost...Tragic!"); + } + public void showTaskList(ArrayList tasks, int taskCount) { System.out.print(separator); if (taskCount == 0) { @@ -78,6 +84,28 @@ public void showTaskAdded(Task task, int taskCount) { System.out.println(separator); } + public void showMarkTaskDone(Task task) { + System.out.println(separator); + System.out.println(" Boom! Task's done and dusted~"); + System.out.println(" " + task); + System.out.println(separator); + } + + public void showMarkTaskUndone(Task task) { + System.out.println(separator); + System.out.println(" Not done yet, but it's still on the radar!"); + System.out.println(" " + task); + System.out.println(separator); + } + + public void showTaskDeleted(Task removedTask, int remainingTasksCount) { + System.out.println(separator); + System.out.println(" Got it! Poof! This task is gone:"); + System.out.println(" " + removedTask); + System.out.println(" Look at that! You've got " + remainingTasksCount + " tasks left to juggle!"); + System.out.println(separator); + } + public void showError(SparkleException e) { System.out.println(separator); System.out.println(e.getMessage()); @@ -90,7 +118,4 @@ public void showExitMessage() { System.out.println(separator); } - public void showLoadingError() { - System.out.println(" Your tasks took a wrong turn and got lost...Tragic!"); - } } diff --git a/test_jar/sparkle.jar b/test_jar/sparkle.jar index 423d11908c12e713c9b472ff1b9b7f59735f62e3..18d828dd7138e12f3d6d35a47cb2ef62b782454a 100644 GIT binary patch delta 10291 zcmZX4WmFzZ)9r)1y9ald00Dv%+}+*Xb%F*gS)#0hv4q++??~?@BQvMx93Oo ztg7B?s(bb7-cx(VdNK$MNkJL{5*`GCg#{()+QlJJLHuR7%>OpIlz*9o8hkv!*xt#M z83Oc=Xsyi0rl1H25NIC;1R?-|K+X<^PS!T2%zp=~7&=?aSUS5f8QT~-JAYTzbzTw0 zJ)s%FTDFbKRu5r0PTXUXR_jbP>%;^+>P#7@h6-S*#{TSO-BDfcKyGYl_ zVBYEBejaDz0bX$2XzWb@USm^LMM}%E3v;w>b=z0pnvIN9gQ*voXE-K^zYRXS z7QIVcZ&EYuW?EzBilR~|*i*2y+lB|GqVxp=8lYkolPX^_(V6FCEKht^>X#)*?XD1P zvj)h0gRzjV!Ev6(u8u=aJls}j)gUI_e#iBIPgrrAZy>eN{} zRGBh9GT*D!?6tpn)}D2|l7mo@&K#&DWuyq=-E&a<4oDiXKRdySc$Ruqot~sPxhAEU z0uU*2rl&fdi+&8M@bu052_?eU(C~B|jm-Q=>X1}V@G40!WrrF<(_PwSLN_9E$*tP9 z5_I?J{_cq@u&ei(RMe14s@}hA+OnlTk*MyvUh^c+h=&EQ+I(y_TdgN*Uiq||U^l*O zJ}NT613*W8F7I?;5WG%k?NNlp;u05~rVVUPZTGJ8WFvI)smCtDCjP!q)WRzZSG zi-J`mb)3w}2~RZ>�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 delta 7048 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 x|3aXDnme&UYGkDU-D$nz))D~(DnbT Date: Fri, 14 Mar 2025 16:30:20 +0800 Subject: [PATCH 35/43] LocalDate implementation --- src/main/java/sparkle/task/Deadline.java | 39 ++++++++++---- src/main/java/sparkle/task/Event.java | 65 +++++++++++++++++------- src/main/java/sparkle/task/Todo.java | 2 +- text-ui-test/EXPECTED.TXT | 61 ++++++++++++++-------- 4 files changed, 117 insertions(+), 50 deletions(-) diff --git a/src/main/java/sparkle/task/Deadline.java b/src/main/java/sparkle/task/Deadline.java index 91ee06443..111bbbc36 100644 --- a/src/main/java/sparkle/task/Deadline.java +++ b/src/main/java/sparkle/task/Deadline.java @@ -1,35 +1,56 @@ package sparkle.task; import sparkle.exception.SparkleException; +import java.time.LocalDateTime; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; public class Deadline extends Task { - protected String by; + protected LocalDateTime by; + private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm"); + private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + private static final DateTimeFormatter OUTPUT_FORMAT = DateTimeFormatter.ofPattern("MMM dd yyyy, h:mm a"); - public Deadline(String description, String by) { + public Deadline(String description, String by) throws SparkleException { super(description); - this.by = by; + this.by = parseDateTime(by); } - public Deadline(String description, boolean isDone, String by) { + public Deadline(String description, boolean isDone, String by) throws SparkleException { super(description, isDone); - this.by = by; + this.by = parseDateTime(by); + } + + private LocalDateTime parseDateTime(String by) throws SparkleException { + String cleanedBy = by.replace(":", ""); + try { + return LocalDateTime.parse(cleanedBy, DATE_TIME_FORMAT); + } catch (DateTimeParseException e1) { + try { + LocalDate date = LocalDate.parse(cleanedBy, DATE_FORMAT); + return date.atTime(23, 59); + } catch (DateTimeParseException e2) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, + "Invalid date format! Please use yyyy-MM-dd or yyyy-MM-dd HHmm (e.g., 2025-02-15 or 2025-02-15 1000)"); + } + } } @Override public String toFileFormat() { - return "D | " + super.toFileFormat() + " | " + by; + return "D | " + super.toFileFormat() + " | " + by.format(DATE_TIME_FORMAT); } public static Deadline fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 4) { - throw new SparkleException( - SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Deadline data"); + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Deadline data"); } return new Deadline(parts[2], parts[1].equals("1"), parts[3]); } @Override public String toString() { - return "[D]" + super.toString() + " (by: " + by + ")"; + return "[D]" + super.toString() + " (by: " + by.format(OUTPUT_FORMAT) + ")"; } } diff --git a/src/main/java/sparkle/task/Event.java b/src/main/java/sparkle/task/Event.java index 311da9813..83c4b9722 100644 --- a/src/main/java/sparkle/task/Event.java +++ b/src/main/java/sparkle/task/Event.java @@ -1,41 +1,68 @@ package sparkle.task; import sparkle.exception.SparkleException; +import java.time.LocalDateTime; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; public class Event extends Task { - protected String from; - protected String to; + protected LocalDateTime from; + protected LocalDateTime to; + private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm"); + private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + private static final DateTimeFormatter OUTPUT_FORMAT = DateTimeFormatter.ofPattern("MMM dd yyyy, h:mm a"); - public Event(String description, String from, String to) { + public Event(String description, String from, String to) throws SparkleException { super(description); - this.from = from; - this.to = to; + this.from = parseDateTime(from, true); + this.to = parseDateTime(to, false); + if (this.from.isAfter(this.to)) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Start time must be before end time!"); + } } - public Event(String description, boolean isDone, String from, String to) { + public Event(String description, boolean isDone, String from, String to) throws SparkleException { super(description, isDone); - this.from = from; - this.to = to; + this.from = parseDateTime(from, true); + this.to = parseDateTime(to, false); + if (this.from.isAfter(this.to)) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, + "Time flows forward, not backward! Fix it!"); + } } - public static Event fromFileFormat(String[] parts) throws SparkleException { - if (parts.length < 4) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Event data"); + private LocalDateTime parseDateTime(String input, boolean isStart) throws SparkleException { + String cleanedInput = input.replace(":", ""); + try { + return LocalDateTime.parse(cleanedInput, DATE_TIME_FORMAT); + } catch (DateTimeParseException e1) { + try { + LocalDate date = LocalDate.parse(cleanedInput, DATE_FORMAT); + return date.atTime(isStart ? 0 : 23, isStart ? 0 : 59); + } catch (DateTimeParseException e2) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, + "Invalid date format! Please use yyyy-MM-dd or yyyy-MM-dd HHmm (e.g., 2025-02-15 or 2025-02-15 1000)"); + } } - String[] fromTo = parts[3].split("-", 2); - if (fromTo.length < 2) { - throw new SparkleException( - SparkleException.ErrorType.INVALID_FORMAT, "Invalid Event time format"); - } - return new Event(parts[2], parts[1].equals("1"), fromTo[0], fromTo[1]); } + @Override public String toFileFormat() { - return "E | " + super.toFileFormat() + " | " + from + "-" + to; + return "E | " + super.toFileFormat() + " | " + from.format(DATE_TIME_FORMAT) + " | " + to.format(DATE_TIME_FORMAT); + } + + public static Event fromFileFormat(String[] parts) throws SparkleException { + if (parts.length < 5) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, + "Yikes! Your event data is completely scrambled!"); + } + return new Event(parts[2], parts[1].equals("1"), parts[3], parts[4]); } @Override public String toString() { - return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; + return "[E]" + super.toString() + " (from: " + from.format(OUTPUT_FORMAT) + " to: " + to.format(OUTPUT_FORMAT) + + ")"; } } diff --git a/src/main/java/sparkle/task/Todo.java b/src/main/java/sparkle/task/Todo.java index 9b3ff70ad..bf2273f61 100644 --- a/src/main/java/sparkle/task/Todo.java +++ b/src/main/java/sparkle/task/Todo.java @@ -18,7 +18,7 @@ public String toFileFormat() { public static Todo fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 3) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Todo data"); + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Oops! Your todo data is a total mess!"); } return new Todo(parts[2], parts[1].equals("1")); } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index d55f24d7f..78324c0b5 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,3 +1,7 @@ + ____________________________________________________________ + Look at that! Your tasks made it back in one piece—miraculous! + ____________________________________________________________ + ____________________________________________________________ Hey hey, I'm Sparkle! ____________________________________________________________ @@ -42,20 +46,20 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Looks like there's nothing fun to mess with... How boring! + Here are the tasks in your list~ + 1. [T][ ] Do assignment ____________________________________________________________ - Tasks loaded successfully! ____________________________________________________________ Let's make it fun! I've added this task: [T][ ] Buy groceries - Looks like you've got 1 tasks in your list~ Better get moving! + Looks like you've got 2 tasks in your list~ Better get moving! ____________________________________________________________ ____________________________________________________________ Let's make it fun! I've added this task: [D][ ] Submit assignment (by: 2025-02-20) - Looks like you've got 2 tasks in your list~ Better get moving! + Looks like you've got 3 tasks in your list~ Better get moving! ____________________________________________________________ ____________________________________________________________ @@ -67,7 +71,7 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ Let's make it fun! I've added this task: [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) - Looks like you've got 3 tasks in your list~ Better get moving! + Looks like you've got 4 tasks in your list~ Better get moving! ____________________________________________________________ ____________________________________________________________ @@ -77,19 +81,22 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ Here are the tasks in your list~ - 1. [T][ ] Buy groceries - 2. [D][ ] Submit assignment (by: 2025-02-20) - 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + 1. [T][ ] Do assignment + 2. [T][ ] Buy groceries + 3. [D][ ] Submit assignment (by: 2025-02-20) + 4. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ + Boom! Task's done and dusted~ - [T][X] Buy groceries + [T][X] Do assignment ____________________________________________________________ ____________________________________________________________ + Boom! Task's done and dusted~ - [D][X] Submit assignment (by: 2025-02-20) + [T][X] Buy groceries ____________________________________________________________ ____________________________________________________________ @@ -99,21 +106,24 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ Here are the tasks in your list~ - 1. [T][X] Buy groceries - 2. [D][X] Submit assignment (by: 2025-02-20) - 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + 1. [T][X] Do assignment + 2. [T][X] Buy groceries + 3. [D][ ] Submit assignment (by: 2025-02-20) + 4. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ + Not done yet, but it's still on the radar! - [T][ ] Buy groceries + [T][ ] Do assignment ____________________________________________________________ ____________________________________________________________ Here are the tasks in your list~ - 1. [T][ ] Buy groceries - 2. [D][X] Submit assignment (by: 2025-02-20) - 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + 1. [T][ ] Do assignment + 2. [T][X] Buy groceries + 3. [D][ ] Submit assignment (by: 2025-02-20) + 4. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ @@ -123,15 +133,24 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ + Got it! Poof! This task is gone: - [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) - Look at that! You've got 2 tasks left to juggle! + [D][ ] Submit assignment (by: 2025-02-20) + Look at that! You've got 3 tasks left to juggle! ____________________________________________________________ ____________________________________________________________ Here are the tasks in your list~ - 1. [T][ ] Buy groceries - 2. [D][X] Submit assignment (by: 2025-02-20) + 1. [T][ ] Do assignment + 2. [T][X] Buy groceries + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + ____________________________________________________________ + + ____________________________________________________________ + Here are the tasks in your list~ + 1. [T][ ] Do assignment + 2. [T][X] Buy groceries + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ From be76cc53b4436fc876fbb1325735506af4ed1543 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 17:13:35 +0800 Subject: [PATCH 36/43] Find method to search task --- src/main/java/sparkle/core/Sparkle.java | 9 +++++++++ src/main/java/sparkle/core/TaskList.java | 10 ++++++++++ src/main/java/sparkle/core/Ui.java | 17 +++++++++++++++++ src/main/java/sparkle/task/Task.java | 4 ++++ 4 files changed, 40 insertions(+) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index 5be50285e..1b607a601 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -6,6 +6,7 @@ import sparkle.task.Todo; import sparkle.exception.SparkleException; +import java.util.ArrayList; import java.util.Scanner; public class Sparkle { @@ -94,6 +95,14 @@ public void run() { Task removedTask = tasks.deleteTask(taskToDelete); ui.showTaskDeleted(removedTask, tasks.size()); break; + case "find": + if (details.isEmpty()) { + throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Find"); + } + // findコマンドに基づき、キーワードでタスクを検索 + ArrayList matchingTasks = tasks.findTasks(details); + ui.showMatchingTasks(matchingTasks); + break; default: throw new SparkleException(SparkleException.ErrorType.UNKNOWN_COMMAND, command); } diff --git a/src/main/java/sparkle/core/TaskList.java b/src/main/java/sparkle/core/TaskList.java index efcb21d3a..26a778914 100644 --- a/src/main/java/sparkle/core/TaskList.java +++ b/src/main/java/sparkle/core/TaskList.java @@ -47,6 +47,16 @@ public ArrayList getTasks() { return tasks; } + public ArrayList findTasks(String keyword) { + ArrayList matchingTasks = new ArrayList<>(); + for (Task task : tasks) { + if (task.getDescription().toLowerCase().contains(keyword.toLowerCase())) { + matchingTasks.add(task); + } + } + return matchingTasks; + } + public int size() { return tasks.size(); } diff --git a/src/main/java/sparkle/core/Ui.java b/src/main/java/sparkle/core/Ui.java index 0fb42cb9b..5478f21c2 100644 --- a/src/main/java/sparkle/core/Ui.java +++ b/src/main/java/sparkle/core/Ui.java @@ -106,6 +106,23 @@ public void showTaskDeleted(Task removedTask, int remainingTasksCount) { System.out.println(separator); } + public void showMatchingTasks(ArrayList matchingTasks) { + if (matchingTasks.isEmpty()) { + System.out.println(separator); + System.out.println(" Nothing here! Did you imagine it?"); + System.out.println(separator); + } else { + System.out.println(separator); + System.out.println(" Look what we've got! Your matching tasks:"); + int index = 1; + for (Task task : matchingTasks) { + System.out.println(" " + index + ". " + task); + index++; + } + System.out.println(separator); + } + } + public void showError(SparkleException e) { System.out.println(separator); System.out.println(e.getMessage()); diff --git a/src/main/java/sparkle/task/Task.java b/src/main/java/sparkle/task/Task.java index 80de38f2e..9d4adbfca 100644 --- a/src/main/java/sparkle/task/Task.java +++ b/src/main/java/sparkle/task/Task.java @@ -20,6 +20,10 @@ public String getStatusIcon() { return (isDone ? "X" : " "); } + public String getDescription() { + return description; + } + public void markAsDone() { this.isDone = true; } From 8f894e7b894159e2ed941c68c53810082f40daf1 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 17:27:07 +0800 Subject: [PATCH 37/43] Revert "LocalDate implementation" This reverts commit 914953fe1610f28201bc41ea4b496d735140424b. --- src/main/java/sparkle/task/Deadline.java | 39 ++++---------- src/main/java/sparkle/task/Event.java | 65 +++++++----------------- src/main/java/sparkle/task/Todo.java | 2 +- text-ui-test/EXPECTED.TXT | 61 ++++++++-------------- 4 files changed, 50 insertions(+), 117 deletions(-) diff --git a/src/main/java/sparkle/task/Deadline.java b/src/main/java/sparkle/task/Deadline.java index 111bbbc36..91ee06443 100644 --- a/src/main/java/sparkle/task/Deadline.java +++ b/src/main/java/sparkle/task/Deadline.java @@ -1,56 +1,35 @@ package sparkle.task; import sparkle.exception.SparkleException; -import java.time.LocalDateTime; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; public class Deadline extends Task { - protected LocalDateTime by; - private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm"); - private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - private static final DateTimeFormatter OUTPUT_FORMAT = DateTimeFormatter.ofPattern("MMM dd yyyy, h:mm a"); + protected String by; - public Deadline(String description, String by) throws SparkleException { + public Deadline(String description, String by) { super(description); - this.by = parseDateTime(by); + this.by = by; } - public Deadline(String description, boolean isDone, String by) throws SparkleException { + public Deadline(String description, boolean isDone, String by) { super(description, isDone); - this.by = parseDateTime(by); - } - - private LocalDateTime parseDateTime(String by) throws SparkleException { - String cleanedBy = by.replace(":", ""); - try { - return LocalDateTime.parse(cleanedBy, DATE_TIME_FORMAT); - } catch (DateTimeParseException e1) { - try { - LocalDate date = LocalDate.parse(cleanedBy, DATE_FORMAT); - return date.atTime(23, 59); - } catch (DateTimeParseException e2) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, - "Invalid date format! Please use yyyy-MM-dd or yyyy-MM-dd HHmm (e.g., 2025-02-15 or 2025-02-15 1000)"); - } - } + this.by = by; } @Override public String toFileFormat() { - return "D | " + super.toFileFormat() + " | " + by.format(DATE_TIME_FORMAT); + return "D | " + super.toFileFormat() + " | " + by; } public static Deadline fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 4) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Deadline data"); + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Deadline data"); } return new Deadline(parts[2], parts[1].equals("1"), parts[3]); } @Override public String toString() { - return "[D]" + super.toString() + " (by: " + by.format(OUTPUT_FORMAT) + ")"; + return "[D]" + super.toString() + " (by: " + by + ")"; } } diff --git a/src/main/java/sparkle/task/Event.java b/src/main/java/sparkle/task/Event.java index 83c4b9722..311da9813 100644 --- a/src/main/java/sparkle/task/Event.java +++ b/src/main/java/sparkle/task/Event.java @@ -1,68 +1,41 @@ package sparkle.task; import sparkle.exception.SparkleException; -import java.time.LocalDateTime; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; public class Event extends Task { - protected LocalDateTime from; - protected LocalDateTime to; - private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm"); - private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - private static final DateTimeFormatter OUTPUT_FORMAT = DateTimeFormatter.ofPattern("MMM dd yyyy, h:mm a"); + protected String from; + protected String to; - public Event(String description, String from, String to) throws SparkleException { + public Event(String description, String from, String to) { super(description); - this.from = parseDateTime(from, true); - this.to = parseDateTime(to, false); - if (this.from.isAfter(this.to)) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Start time must be before end time!"); - } + this.from = from; + this.to = to; } - public Event(String description, boolean isDone, String from, String to) throws SparkleException { + public Event(String description, boolean isDone, String from, String to) { super(description, isDone); - this.from = parseDateTime(from, true); - this.to = parseDateTime(to, false); - if (this.from.isAfter(this.to)) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, - "Time flows forward, not backward! Fix it!"); - } + this.from = from; + this.to = to; } - private LocalDateTime parseDateTime(String input, boolean isStart) throws SparkleException { - String cleanedInput = input.replace(":", ""); - try { - return LocalDateTime.parse(cleanedInput, DATE_TIME_FORMAT); - } catch (DateTimeParseException e1) { - try { - LocalDate date = LocalDate.parse(cleanedInput, DATE_FORMAT); - return date.atTime(isStart ? 0 : 23, isStart ? 0 : 59); - } catch (DateTimeParseException e2) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, - "Invalid date format! Please use yyyy-MM-dd or yyyy-MM-dd HHmm (e.g., 2025-02-15 or 2025-02-15 1000)"); - } + public static Event fromFileFormat(String[] parts) throws SparkleException { + if (parts.length < 4) { + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Event data"); } + String[] fromTo = parts[3].split("-", 2); + if (fromTo.length < 2) { + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, "Invalid Event time format"); + } + return new Event(parts[2], parts[1].equals("1"), fromTo[0], fromTo[1]); } - @Override public String toFileFormat() { - return "E | " + super.toFileFormat() + " | " + from.format(DATE_TIME_FORMAT) + " | " + to.format(DATE_TIME_FORMAT); - } - - public static Event fromFileFormat(String[] parts) throws SparkleException { - if (parts.length < 5) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, - "Yikes! Your event data is completely scrambled!"); - } - return new Event(parts[2], parts[1].equals("1"), parts[3], parts[4]); + return "E | " + super.toFileFormat() + " | " + from + "-" + to; } @Override public String toString() { - return "[E]" + super.toString() + " (from: " + from.format(OUTPUT_FORMAT) + " to: " + to.format(OUTPUT_FORMAT) - + ")"; + return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; } } diff --git a/src/main/java/sparkle/task/Todo.java b/src/main/java/sparkle/task/Todo.java index bf2273f61..9b3ff70ad 100644 --- a/src/main/java/sparkle/task/Todo.java +++ b/src/main/java/sparkle/task/Todo.java @@ -18,7 +18,7 @@ public String toFileFormat() { public static Todo fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 3) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Oops! Your todo data is a total mess!"); + throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Todo data"); } return new Todo(parts[2], parts[1].equals("1")); } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 78324c0b5..d55f24d7f 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,3 @@ - ____________________________________________________________ - Look at that! Your tasks made it back in one piece—miraculous! - ____________________________________________________________ - ____________________________________________________________ Hey hey, I'm Sparkle! ____________________________________________________________ @@ -46,20 +42,20 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Here are the tasks in your list~ - 1. [T][ ] Do assignment + Looks like there's nothing fun to mess with... How boring! ____________________________________________________________ + Tasks loaded successfully! ____________________________________________________________ Let's make it fun! I've added this task: [T][ ] Buy groceries - Looks like you've got 2 tasks in your list~ Better get moving! + Looks like you've got 1 tasks in your list~ Better get moving! ____________________________________________________________ ____________________________________________________________ Let's make it fun! I've added this task: [D][ ] Submit assignment (by: 2025-02-20) - Looks like you've got 3 tasks in your list~ Better get moving! + Looks like you've got 2 tasks in your list~ Better get moving! ____________________________________________________________ ____________________________________________________________ @@ -71,7 +67,7 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ Let's make it fun! I've added this task: [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) - Looks like you've got 4 tasks in your list~ Better get moving! + Looks like you've got 3 tasks in your list~ Better get moving! ____________________________________________________________ ____________________________________________________________ @@ -81,22 +77,19 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ Here are the tasks in your list~ - 1. [T][ ] Do assignment - 2. [T][ ] Buy groceries - 3. [D][ ] Submit assignment (by: 2025-02-20) - 4. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + 1. [T][ ] Buy groceries + 2. [D][ ] Submit assignment (by: 2025-02-20) + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ - Boom! Task's done and dusted~ - [T][X] Do assignment + [T][X] Buy groceries ____________________________________________________________ ____________________________________________________________ - Boom! Task's done and dusted~ - [T][X] Buy groceries + [D][X] Submit assignment (by: 2025-02-20) ____________________________________________________________ ____________________________________________________________ @@ -106,24 +99,21 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ Here are the tasks in your list~ - 1. [T][X] Do assignment - 2. [T][X] Buy groceries - 3. [D][ ] Submit assignment (by: 2025-02-20) - 4. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + 1. [T][X] Buy groceries + 2. [D][X] Submit assignment (by: 2025-02-20) + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ - Not done yet, but it's still on the radar! - [T][ ] Do assignment + [T][ ] Buy groceries ____________________________________________________________ ____________________________________________________________ Here are the tasks in your list~ - 1. [T][ ] Do assignment - 2. [T][X] Buy groceries - 3. [D][ ] Submit assignment (by: 2025-02-20) - 4. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + 1. [T][ ] Buy groceries + 2. [D][X] Submit assignment (by: 2025-02-20) + 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) ____________________________________________________________ ____________________________________________________________ @@ -133,24 +123,15 @@ NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN ____________________________________________________________ ____________________________________________________________ - Got it! Poof! This task is gone: - [D][ ] Submit assignment (by: 2025-02-20) - Look at that! You've got 3 tasks left to juggle! - ____________________________________________________________ - - ____________________________________________________________ - Here are the tasks in your list~ - 1. [T][ ] Do assignment - 2. [T][X] Buy groceries - 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + Look at that! You've got 2 tasks left to juggle! ____________________________________________________________ ____________________________________________________________ Here are the tasks in your list~ - 1. [T][ ] Do assignment - 2. [T][X] Buy groceries - 3. [E][ ] Meeting (from: 2025-02-15 10:00 to: 2025-02-15 12:00) + 1. [T][ ] Buy groceries + 2. [D][X] Submit assignment (by: 2025-02-20) ____________________________________________________________ ____________________________________________________________ From 8db56e4bf4d12907f79610b1e635932c05d650f0 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 17:42:30 +0800 Subject: [PATCH 38/43] Add Javadoc to Sparkle.java --- src/main/java/sparkle/core/Sparkle.java | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index 5be50285e..a6b11a779 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -8,12 +8,25 @@ import java.util.Scanner; +/** + * This class represents the main logic of the Sparkle application, which + * manages tasks. + * It interacts with the user, processes commands, and updates the task list + * accordingly. + */ public class Sparkle { private Ui ui; private Storage storage; private TaskList tasks; + /** + * Initializes the Sparkle application with the given file path. + * It sets up the UI, storage, and loads the task list from the specified file. + * If loading the tasks fails, it initializes an empty task list. + * + * @param filePath The file path to load the tasks from. + */ public Sparkle(String filePath) { ui = new Ui(); storage = new Storage(); @@ -27,6 +40,12 @@ public Sparkle(String filePath) { } } + /** + * Runs the Sparkle application, continuously accepting user input, processing + * commands, + * and displaying relevant information. The application exits when the user + * types the "bye" command. + */ public void run() { ui.showLogo(); ui.showGreeting(); @@ -106,6 +125,13 @@ public void run() { } } + /** + * The entry point of the Sparkle application. It initializes the application + * with the file path + * and starts the application by calling the `run()` method. + * + * @param args Command-line arguments (not used). + */ public static void main(String[] args) { new Sparkle("data/sparkle.txt").run(); } From a0c4cae9cc19033f6f668f69b4e88e1f19a2ec40 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 17:52:35 +0800 Subject: [PATCH 39/43] Add Javadoc to task and subclassed --- src/main/java/sparkle/task/Deadline.java | 58 ++++++++++++++++++++++++ src/main/java/sparkle/task/Event.java | 53 ++++++++++++++++++++++ src/main/java/sparkle/task/Task.java | 52 +++++++++++++++++++++ src/main/java/sparkle/task/Todo.java | 40 ++++++++++++++++ 4 files changed, 203 insertions(+) diff --git a/src/main/java/sparkle/task/Deadline.java b/src/main/java/sparkle/task/Deadline.java index 111bbbc36..508c5c6de 100644 --- a/src/main/java/sparkle/task/Deadline.java +++ b/src/main/java/sparkle/task/Deadline.java @@ -6,22 +6,58 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +/** + * Represents a deadline task that has a specified deadline time. + * Inherits from the Task class and includes functionality for handling + * deadlines. + */ public class Deadline extends Task { + + // Field to store the deadline time protected LocalDateTime by; + + // DateTime format patterns used for parsing and formatting dates private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm"); private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); private static final DateTimeFormatter OUTPUT_FORMAT = DateTimeFormatter.ofPattern("MMM dd yyyy, h:mm a"); + /** + * Constructs a Deadline object with the specified description and deadline + * time. + * + * @param description A brief description of the task. + * @param by The deadline in the format "yyyy-MM-dd HHmm" or + * "yyyy-MM-dd". + * @throws SparkleException If the provided date/time format is invalid. + */ public Deadline(String description, String by) throws SparkleException { super(description); this.by = parseDateTime(by); } + /** + * Constructs a Deadline object with the specified description, completion + * status, and deadline time. + * + * @param description A brief description of the task. + * @param isDone A boolean indicating whether the task is marked as done. + * @param by The deadline in the format "yyyy-MM-dd HHmm" or + * "yyyy-MM-dd". + * @throws SparkleException If the provided date/time format is invalid. + */ public Deadline(String description, boolean isDone, String by) throws SparkleException { super(description, isDone); this.by = parseDateTime(by); } + /** + * Parses the deadline time string into a LocalDateTime object. + * + * @param by The deadline string to be parsed. + * @return A LocalDateTime object corresponding to the deadline. + * @throws SparkleException If the input string cannot be parsed into a valid + * date/time format. + */ private LocalDateTime parseDateTime(String by) throws SparkleException { String cleanedBy = by.replace(":", ""); try { @@ -37,11 +73,26 @@ private LocalDateTime parseDateTime(String by) throws SparkleException { } } + /** + * Converts the deadline task into a string format suitable for saving to a + * file. + * + * @return A string representation of the deadline in a format suitable for + * storage. + */ @Override public String toFileFormat() { return "D | " + super.toFileFormat() + " | " + by.format(DATE_TIME_FORMAT); } + /** + * Creates a Deadline object from a string array formatted for file loading. + * + * @param parts A string array containing deadline data in the format [type, + * done, description, by]. + * @return A Deadline object initialized with the data from the array. + * @throws SparkleException If the input data is in an invalid format. + */ public static Deadline fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 4) { throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Deadline data"); @@ -49,6 +100,13 @@ public static Deadline fromFileFormat(String[] parts) throws SparkleException { return new Deadline(parts[2], parts[1].equals("1"), parts[3]); } + /** + * Returns a string representation of the deadline task, including its + * description and deadline time. + * + * @return A string representation of the deadline task in the format + * "[D][description] (by: [deadline])". + */ @Override public String toString() { return "[D]" + super.toString() + " (by: " + by.format(OUTPUT_FORMAT) + ")"; diff --git a/src/main/java/sparkle/task/Event.java b/src/main/java/sparkle/task/Event.java index 83c4b9722..0326939c6 100644 --- a/src/main/java/sparkle/task/Event.java +++ b/src/main/java/sparkle/task/Event.java @@ -6,13 +6,28 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +/** + * Represents an event with a start time and end time. + */ public class Event extends Task { + protected LocalDateTime from; protected LocalDateTime to; private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm"); private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); private static final DateTimeFormatter OUTPUT_FORMAT = DateTimeFormatter.ofPattern("MMM dd yyyy, h:mm a"); + /** + * Constructs an Event with a description, start time, and end time. + * + * @param description The description of the event. + * @param from The start time in the format "yyyy-MM-dd HHmm" or + * "yyyy-MM-dd". + * @param to The end time in the format "yyyy-MM-dd HHmm" or + * "yyyy-MM-dd". + * @throws SparkleException If the time format is invalid or the start time is + * after the end time. + */ public Event(String description, String from, String to) throws SparkleException { super(description); this.from = parseDateTime(from, true); @@ -22,6 +37,19 @@ public Event(String description, String from, String to) throws SparkleException } } + /** + * Constructs an Event with a description, completion status, start time, and + * end time. + * + * @param description The description of the event. + * @param isDone Whether the event is completed. + * @param from The start time in the format "yyyy-MM-dd HHmm" or + * "yyyy-MM-dd". + * @param to The end time in the format "yyyy-MM-dd HHmm" or + * "yyyy-MM-dd". + * @throws SparkleException If the time format is invalid or the start time is + * after the end time. + */ public Event(String description, boolean isDone, String from, String to) throws SparkleException { super(description, isDone); this.from = parseDateTime(from, true); @@ -32,6 +60,14 @@ public Event(String description, boolean isDone, String from, String to) throws } } + /** + * Parses a date/time string into a LocalDateTime object. + * + * @param input The date/time string to parse. + * @param isStart Whether the input represents a start time. + * @return The parsed LocalDateTime object. + * @throws SparkleException If the input string is in an invalid format. + */ private LocalDateTime parseDateTime(String input, boolean isStart) throws SparkleException { String cleanedInput = input.replace(":", ""); try { @@ -47,11 +83,23 @@ private LocalDateTime parseDateTime(String input, boolean isStart) throws Sparkl } } + /** + * Converts the event to a format suitable for saving to a file. + * + * @return The event data as a string for file storage. + */ @Override public String toFileFormat() { return "E | " + super.toFileFormat() + " | " + from.format(DATE_TIME_FORMAT) + " | " + to.format(DATE_TIME_FORMAT); } + /** + * Creates an Event object from a file format string array. + * + * @param parts The string array representing event data. + * @return The Event object created from the data. + * @throws SparkleException If the data is in an invalid format. + */ public static Event fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 5) { throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, @@ -60,6 +108,11 @@ public static Event fromFileFormat(String[] parts) throws SparkleException { return new Event(parts[2], parts[1].equals("1"), parts[3], parts[4]); } + /** + * Returns a string representation of the event. + * + * @return A string representation of the event with start and end times. + */ @Override public String toString() { return "[E]" + super.toString() + " (from: " + from.format(OUTPUT_FORMAT) + " to: " + to.format(OUTPUT_FORMAT) diff --git a/src/main/java/sparkle/task/Task.java b/src/main/java/sparkle/task/Task.java index 80de38f2e..270e8f8c4 100644 --- a/src/main/java/sparkle/task/Task.java +++ b/src/main/java/sparkle/task/Task.java @@ -2,36 +2,81 @@ import sparkle.exception.SparkleException; +/** + * Represents a task with a description and completion status. + * This class provides functionality for marking a task as done or undone, + * converting it to and from a file format, and retrieving the task's string + * representation. + */ public class Task { protected String description; protected boolean isDone; + /** + * Constructs a Task object with the specified description. + * The task is initially marked as not done. + * + * @param description A brief description of the task. + */ public Task(String description) { this.description = description; this.isDone = false; } + /** + * Constructs a Task object with the specified description and completion + * status. + * + * @param description A brief description of the task. + * @param isDone A boolean indicating whether the task is marked as done. + */ public Task(String description, boolean isDone) { this.description = description; this.isDone = isDone; } + /** + * Returns the status icon of the task, representing whether the task is done or + * not. + * + * @return A string representing the task's completion status ("X" for done, " " + * for undone). + */ public String getStatusIcon() { return (isDone ? "X" : " "); } + /** + * Marks the task as done. + */ public void markAsDone() { this.isDone = true; } + /** + * Marks the task as undone. + */ public void markAsUndone() { this.isDone = false; } + /** + * Converts the Task object into a string format suitable for saving to a file. + * + * @return A string representation of the task in a format suitable for storage. + */ public String toFileFormat() { return (isDone ? "1" : "0") + " | " + description; } + /** + * Creates a Task object from a string array formatted for file loading. + * + * @param parts A string array containing task data in the format [type, done, + * description]. + * @return A Task object initialized with the data from the array. + * @throws SparkleException If the input data is in an invalid format. + */ public static Task fromFileFormat(String[] parts) throws SparkleException { char type = parts[0].charAt(0); @@ -49,6 +94,13 @@ public static Task fromFileFormat(String[] parts) throws SparkleException { } } + /** + * Returns a string representation of the task, including its status and + * description. + * + * @return A string representation of the task in the format "[status] + * description". + */ @Override public String toString() { return "[" + getStatusIcon() + "] " + description; diff --git a/src/main/java/sparkle/task/Todo.java b/src/main/java/sparkle/task/Todo.java index bf2273f61..dc6884c84 100644 --- a/src/main/java/sparkle/task/Todo.java +++ b/src/main/java/sparkle/task/Todo.java @@ -2,20 +2,53 @@ import sparkle.exception.SparkleException; +/** + * Represents a Todo task with a description and completion status. + * Inherits from the Task class and includes functionality for handling Todo + * tasks. + */ public class Todo extends Task { + + /** + * Constructs a Todo object with the specified description. + * The task is initially marked as not done. + * + * @param description A brief description of the task. + */ public Todo(String description) { super(description); } + /** + * Constructs a Todo object with the specified description and completion + * status. + * + * @param description A brief description of the task. + * @param isDone A boolean indicating whether the task is marked as done. + */ public Todo(String description, boolean isDone) { super(description, isDone); } + /** + * Converts the Todo task into a string format suitable for saving to a file. + * + * @return A string representation of the Todo task in a format suitable for + * storage. + */ @Override public String toFileFormat() { return "T | " + super.toFileFormat(); } + /** + * Creates a Todo object from a string array formatted for file loading. + * + * @param parts A string array containing Todo data in the format [type, done, + * description]. + * @return A Todo object initialized with the data from the array. + * @throws SparkleException If the input data is in an invalid format. + */ public static Todo fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 3) { throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Oops! Your todo data is a total mess!"); @@ -23,6 +56,13 @@ public static Todo fromFileFormat(String[] parts) throws SparkleException { return new Todo(parts[2], parts[1].equals("1")); } + /** + * Returns a string representation of the Todo task, including its description + * and completion status. + * + * @return A string representation of the Todo task in the format + * "[T][description]". + */ @Override public String toString() { return "[T]" + super.toString(); From 4a8627bd3f5d26f2944f9e283d397d5f50b5b51a Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 22:21:53 +0800 Subject: [PATCH 40/43] Add Javadoc to all classes --- src/main/java/sparkle/core/Parser.java | 22 +- src/main/java/sparkle/core/Sparkle.java | 38 ++- src/main/java/sparkle/core/Storage.java | 83 +++--- src/main/java/sparkle/core/TaskList.java | 112 ++++--- src/main/java/sparkle/core/Ui.java | 273 ++++++++++-------- .../sparkle/exception/SparkleException.java | 15 + src/main/java/sparkle/task/Deadline.java | 25 ++ src/main/java/sparkle/task/Event.java | 21 ++ src/main/java/sparkle/task/Task.java | 39 +++ src/main/java/sparkle/task/Todo.java | 28 ++ 10 files changed, 459 insertions(+), 197 deletions(-) diff --git a/src/main/java/sparkle/core/Parser.java b/src/main/java/sparkle/core/Parser.java index b445d99a0..1f04919b1 100644 --- a/src/main/java/sparkle/core/Parser.java +++ b/src/main/java/sparkle/core/Parser.java @@ -1,11 +1,21 @@ package sparkle.core; +/** + * The {@code Parser} class is responsible for processing user input. It splits the input into a + * command and its associated details. + */ public class Parser { - public static String[] parse(String userInput) { - String[] commandParts = userInput.split(" ", 2); - String command = commandParts[0].toLowerCase(); - String details = commandParts.length > 1 ? commandParts[1].trim() : ""; - return new String[]{command, details}; - } + /** + * Parses the user input into a command and its details. + * + * @param userInput The raw user input string. + * @return An array where the first element is the command and the second element is the details. + */ + public static String[] parse(String userInput) { + String[] commandParts = userInput.split(" ", 2); + String command = commandParts[0].toLowerCase(); + String details = commandParts.length > 1 ? commandParts[1].trim() : ""; + return new String[] {command, details}; + } } diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index 5be50285e..f0923c304 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -1,19 +1,27 @@ package sparkle.core; +import java.util.Scanner; +import sparkle.exception.SparkleException; import sparkle.task.Deadline; import sparkle.task.Event; import sparkle.task.Task; import sparkle.task.Todo; -import sparkle.exception.SparkleException; - -import java.util.Scanner; +/** + * The {@code Sparkle} class represents the main chatbot application. It handles user input, task + * management, and interaction with the storage system. + */ public class Sparkle { private Ui ui; private Storage storage; private TaskList tasks; + /** + * Initializes the Sparkle chatbot with a given file path for task storage. + * + * @param filePath The file path where tasks are stored. + */ public Sparkle(String filePath) { ui = new Ui(); storage = new Storage(); @@ -27,6 +35,7 @@ public Sparkle(String filePath) { } } + /** Runs the chatbot, processing user input in a loop until the "bye" command is given. */ public void run() { ui.showLogo(); ui.showGreeting(); @@ -59,7 +68,8 @@ public void run() { break; case "todo": if (details.isEmpty()) { - throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); + throw new SparkleException( + SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); } tasks.addTask(new Todo(details)); ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); @@ -70,7 +80,8 @@ public void run() { } String[] deadlineParts = details.split(" /by ", 2); if (deadlineParts.length < 2) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, "Need a /by time! Or do you plan to finish it... never?"); } tasks.addTask(new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim())); @@ -78,15 +89,19 @@ public void run() { break; case "event": if (details.isEmpty()) { - throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Event"); + throw new SparkleException( + SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Event"); } String[] eventParts = details.split(" /from ", 2); if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, - "Oops! You forgot the time slots! Gotta add both /from and /to, or this show ain't starting!"); + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, + "Oops! You forgot the time slots! Gotta add both /from and /to, or this show" + + " ain't starting!"); } String[] timeParts = eventParts[1].split(" /to ", 2); - tasks.addTask(new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); + tasks.addTask( + new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); break; case "delete": @@ -106,6 +121,11 @@ public void run() { } } + /** + * The main entry point for the Sparkle chatbot. + * + * @param args Command-line arguments. + */ public static void main(String[] args) { new Sparkle("data/sparkle.txt").run(); } diff --git a/src/main/java/sparkle/core/Storage.java b/src/main/java/sparkle/core/Storage.java index 9dce794ba..c3c66588b 100644 --- a/src/main/java/sparkle/core/Storage.java +++ b/src/main/java/sparkle/core/Storage.java @@ -1,47 +1,60 @@ +/** Handles loading and saving of tasks from and to a file. */ package sparkle.core; -import sparkle.exception.SparkleException; -import sparkle.task.Task; - import java.io.*; import java.util.ArrayList; import java.util.Scanner; +import sparkle.exception.SparkleException; +import sparkle.task.Task; public class Storage { - private static final String FILE_PATH = "./data/sparkle.txt"; - private static final String DIRECTORY_PATH = "./data"; - - public ArrayList load() throws SparkleException { - ArrayList newtasks = new ArrayList<>(); - File file = new File(FILE_PATH); - - if (!file.exists()) { - return newtasks; - } - - try (Scanner scanner = new Scanner(file)) { - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - String[] parts = line.split(" \\| "); - newtasks.add(Task.fromFileFormat(parts)); - } - } catch (FileNotFoundException e) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "That file's playing hide and seek… and winning!"); - } - return newtasks; + private static final String FILE_PATH = "./data/sparkle.txt"; + private static final String DIRECTORY_PATH = "./data"; + + /** + * Loads tasks from the specified file. + * + * @return A list of tasks loaded from the file. + * @throws SparkleException If the file format is invalid or cannot be read. + */ + public ArrayList load() throws SparkleException { + ArrayList newtasks = new ArrayList<>(); + File file = new File(FILE_PATH); + + if (!file.exists()) { + return newtasks; } - public void save(ArrayList tasks) { - try { - new File(DIRECTORY_PATH).mkdirs(); - BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH)); - for (Task task : tasks) { - writer.write(task.toFileFormat() + "\n"); - } - writer.close(); - } catch (IOException e) { - System.out.println(" Task list just went poof! Try saving again!"); - } + try (Scanner scanner = new Scanner(file)) { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] parts = line.split(" \\| "); + newtasks.add(Task.fromFileFormat(parts)); + } + } catch (FileNotFoundException e) { + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, + "That file's playing hide and seek… and winning!"); + } + return newtasks; + } + + /** + * Saves the given list of tasks to the file. + * + * @param tasks The list of tasks to save. + */ + public void save(ArrayList tasks) { + try { + new File(DIRECTORY_PATH).mkdirs(); + BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH)); + for (Task task : tasks) { + writer.write(task.toFileFormat() + "\n"); + } + writer.close(); + } catch (IOException e) { + System.out.println(" Task list just went poof! Try saving again!"); } + } } diff --git a/src/main/java/sparkle/core/TaskList.java b/src/main/java/sparkle/core/TaskList.java index efcb21d3a..0c6799d7c 100644 --- a/src/main/java/sparkle/core/TaskList.java +++ b/src/main/java/sparkle/core/TaskList.java @@ -1,53 +1,97 @@ package sparkle.core; -import sparkle.exception.SparkleException; import java.util.ArrayList; +import sparkle.exception.SparkleException; import sparkle.task.Task; +/** + * The {@code TaskList} class manages a collection of tasks. It provides methods to add, remove, and + * modify tasks. + */ public class TaskList { - private ArrayList tasks; + private ArrayList tasks; - public TaskList() { - tasks = new ArrayList<>(); - } + /** Constructs an empty {@code TaskList}. */ + public TaskList() { + tasks = new ArrayList<>(); + } - public TaskList(ArrayList tasks) { - this.tasks = tasks; - } + /** + * Constructs a {@code TaskList} with the given list of tasks. + * + * @param tasks The initial list of tasks. + */ + public TaskList(ArrayList tasks) { + this.tasks = tasks; + } - public void addTask(Task task) { - tasks.add(task); - } + /** + * Adds a task to the list. + * + * @param task The task to be added. + */ + public void addTask(Task task) { + tasks.add(task); + } - public Task deleteTask(int taskNumber) throws SparkleException { - if (taskNumber < 0 || taskNumber >= tasks.size()) { - throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); - } - Task deleteTask = tasks.get(taskNumber); - tasks.remove(taskNumber); - return deleteTask; + /** + * Deletes a task from the list. + * + * @param taskNumber The index of the task to be deleted. + * @return The deleted task. + * @throws SparkleException If the task number is invalid. + */ + public Task deleteTask(int taskNumber) throws SparkleException { + if (taskNumber < 0 || taskNumber >= tasks.size()) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } + Task deleteTask = tasks.get(taskNumber); + tasks.remove(taskNumber); + return deleteTask; + } - public void markTaskAsDone(int taskNumber) throws SparkleException { - if (taskNumber < 0 || taskNumber >= tasks.size()) { - throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); - } - tasks.get(taskNumber).markAsDone(); + /** + * Marks a task as done. + * + * @param taskNumber The index of the task to be marked as done. + * @throws SparkleException If the task number is invalid. + */ + public void markTaskAsDone(int taskNumber) throws SparkleException { + if (taskNumber < 0 || taskNumber >= tasks.size()) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } + tasks.get(taskNumber).markAsDone(); + } - public void markTaskAsUndone(int taskNumber) throws SparkleException { - if (taskNumber < 0 || taskNumber >= tasks.size()) { - throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); - } - tasks.get(taskNumber).markAsUndone(); + /** + * Marks a task as undone. + * + * @param taskNumber The index of the task to be marked as undone. + * @throws SparkleException If the task number is invalid. + */ + public void markTaskAsUndone(int taskNumber) throws SparkleException { + if (taskNumber < 0 || taskNumber >= tasks.size()) { + throw new SparkleException(SparkleException.ErrorType.INVALID_TASK_NUMBER, ""); } + tasks.get(taskNumber).markAsUndone(); + } - public ArrayList getTasks() { - return tasks; - } + /** + * Returns the list of tasks. + * + * @return The list of tasks. + */ + public ArrayList getTasks() { + return tasks; + } - public int size() { - return tasks.size(); - } + /** + * Returns the number of tasks in the list. + * + * @return The number of tasks. + */ + public int size() { + return tasks.size(); + } } diff --git a/src/main/java/sparkle/core/Ui.java b/src/main/java/sparkle/core/Ui.java index 0fb42cb9b..e877b5fbb 100644 --- a/src/main/java/sparkle/core/Ui.java +++ b/src/main/java/sparkle/core/Ui.java @@ -1,121 +1,168 @@ package sparkle.core; -import sparkle.task.Task; -import sparkle.exception.SparkleException; import java.util.ArrayList; +import sparkle.exception.SparkleException; +import sparkle.task.Task; +/** + * The {@code Ui} class handles user interactions by displaying messages and task information to the + * console. + */ public class Ui { - private static final String separator = " ____________________________________________________________\n"; - private static String logo = "NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN\n" - + "NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN\n" - + "NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN\n" - + "NHZOvz1>>>>>;>;jHMMHHMMHHngHHbkWMMHH@MMMb .dHMs?WmaJJHpHWWMNZzOUUWHHHggkM\n" - + "#Hz>>>>>;>>;;;(MMNqkkkkqHHHHWHHH@@@@MMMM@N. d@MI<~(?>`` ?WHHHN<;<(JHHd@KzM\n" - + "#Hz>;;;<::~~<:~~~:~JMgHppWWWY(dM@MHHH@@MMMHM@@@@N-<(v7<-__ `.-~_(dHkWbpbbbbSM\n" - + "NH>~~:~~~(MmHWWY=(WWHM#XXMH@@H@@@@@@g@@Nv! (61j.~dWWHgHHWWKM\n" - + "#K>~~_jY.(HHWXM@@Mggg@HHgB&HgmgHmmkwXNSWHHWvWYTk-..______~~JMHHggggqHM\n" - + "NK!_..%._(kHWM@@MgmggHH9! (HMHHqqqqgHHHHWHHkUkU9>~~~~~~~~~~(MWHHgggkWM\n" - + "NK_...~.-dHdM@MMgmmgHHm...J0kWHkppkHmHHkHHUKHWm.......-((-_(HNVWHmgHSM\n" - + "NH<...~-JWMHMHHggqgHHYUMMHHwHWHpffppHWpbbbod@g@@M@@@HHMWNmazuHffpHMHXM\n" - + "#HJM@gH:?-``````` `_` `` .! __?~(HgHHkqqkkqHkXfppWHMMMh-jM\n" - + "#HHgmKMHpHHWI;_ jc;;<1d$-.dHHqH$ ``` JY-JWXWVfffWkUUWMMRM\n" - + "NHGdCldgHSXHkWXHR `````jk1<_(jr``.V!?WHH9Y>`` .``` .dpqWbHkWfudkHqTAwM\n" - + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" - + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" - + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; - - public void showLogo() { - - System.out.println(separator + " Hey hey, I'm Sparkle!\n" + separator + logo); - } - - public void showGreeting() { - System.out.println(separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); - } - - public void showLoadingSuccess() { - System.out.println( - separator + " Look at that! Your tasks made it back in one piece—miraculous!\n" + separator); - } - - public void showLoadingError() { - System.out.println(separator + " Your tasks took a wrong turn and got lost...Tragic!"); - } - - public void showTaskList(ArrayList tasks, int taskCount) { - System.out.print(separator); - if (taskCount == 0) { - System.out.println(" Looks like there's nothing fun to mess with... How boring!"); - } else { - System.out.println(" Here are the tasks in your list~ "); - for (int i = 0; i < tasks.size(); i++) { - System.out.println(" " + (i + 1) + ". " + tasks.get(i)); - } - } - System.out.println(separator); + private static final String separator = + " ____________________________________________________________\n"; + private static String logo = + "NNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNN\n" + + "NMNNMHXXyVVyyHqqqqkHHmWggH4k<<>>>>??1C?Tz111lOwXWMHgHMM@@@@@@@@NXMNNMN\n" + + "NNMMSZXUUU0VOIWHkkkkkkHHHlXH2<;;;<<+J~..uvx1zZUWHMHHHMMM@@@@@@@@NXMMNN\n" + + "NHZOvz1>>>>>;>;jHMMHHMMHHngHHbkWMMHH@MMMb .dHMs?WmaJJHpHWWMNZzOUUWHHHggkM\n" + + "#Hz>>>>>;>>;;;(MMNqkkkkqHHHHWHHH@@@@MMMM@N. d@MI<~(?>`` ?WHHHN<;<(JHHd@KzM\n" + + "#Hz>;;;<::~~<:~~~:~JMgHppWWWY(dM@MHHH@@MMMHM@@@@N-<(v7<-__ `.-~_(dHkWbpbbbbSM\n" + + "NH>~~:~~~(MmHWWY=(WWHM#XXMH@@H@@@@@@g@@Nv! (61j.~dWWHgHHWWKM\n" + + "#K>~~_jY.(HHWXM@@Mggg@HHgB&HgmgHmmkwXNSWHHWvWYTk-..______~~JMHHggggqHM\n" + + "NK!_..%._(kHWM@@MgmggHH9! (HMHHqqqqgHHHHWHHkUkU9>~~~~~~~~~~(MWHHgggkWM\n" + + "NK_...~.-dHdM@MMgmmgHHm...J0kWHkppkHmHHkHHUKHWm.......-((-_(HNVWHmgHSM\n" + + "NH<...~-JWMHMHHggqgHHYUMMHHwHWHpffppHWpbbbod@g@@M@@@HHMWNmazuHffpHMHXM\n" + + "#HJM@gH:?-``````` `_` `` .! __?~(HgHHkqqkkqHkXfppWHMMMh-jM\n" + + "#HHgmKMHpHHWI;_ jc;;<1d$-.dHHqH$ ``` JY-JWXWVfffWkUUWMMRM\n" + + "NHGdCldgHSXHkWXHR `````jk1<_(jr``.V!?WHH9Y>`` .``` .dpqWbHkWfudkHqTAwM\n" + + "NMNmkyd@HZXHkHww$``````.Wz7Iv!`.J=?TYY>:<~``` ..`` JHWHWHpVWIdHsvXqNMN\n" + + "NNNNNkdMHXXHWH2uC```````jL```.JY` -_~~`````` -`.``.HmHHfpWWWRdWVwW#NNN\n" + + "NMNNNNmQmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmdNNNMN"; + + /** Displays the Sparkle logo. */ + public void showLogo() { + System.out.println(separator + " Hey hey, I'm Sparkle!\n" + separator + logo); + } + + /** Displays the greeting message. */ + public void showGreeting() { + System.out.println( + separator + " Got any cool, daring quests or risky biz? Just hit me up!\n" + separator); + } + + /** Displays a message indicating that tasks have been successfully loaded. */ + public void showLoadingSuccess() { + System.out.println( + separator + + " Look at that! Your tasks made it back in one piece—miraculous!\n" + + separator); + } + + /** Displays an error message when loading tasks fails. */ + public void showLoadingError() { + System.out.println(separator + " Your tasks took a wrong turn and got lost...Tragic!"); + } + + /** + * Displays the list of tasks. + * + * @param tasks The list of tasks to display. + * @param taskCount The number of tasks in the list. + */ + public void showTaskList(ArrayList tasks, int taskCount) { + System.out.print(separator); + if (taskCount == 0) { + System.out.println(" Looks like there's nothing fun to mess with... How boring!"); + } else { + System.out.println(" Here are the tasks in your list~ "); + for (int i = 0; i < tasks.size(); i++) { + System.out.println(" " + (i + 1) + ". " + tasks.get(i)); + } } - - public void showTaskAdded(Task task, int taskCount) { - System.out.print(separator); - System.out.println(" Let's make it fun! I've added this task:"); - System.out.println(" " + task); - System.out.println(" Looks like you've got " + taskCount + " tasks in your list~ Better get moving!"); - System.out.println(separator); - } - - public void showMarkTaskDone(Task task) { - System.out.println(separator); - System.out.println(" Boom! Task's done and dusted~"); - System.out.println(" " + task); - System.out.println(separator); - } - - public void showMarkTaskUndone(Task task) { - System.out.println(separator); - System.out.println(" Not done yet, but it's still on the radar!"); - System.out.println(" " + task); - System.out.println(separator); - } - - public void showTaskDeleted(Task removedTask, int remainingTasksCount) { - System.out.println(separator); - System.out.println(" Got it! Poof! This task is gone:"); - System.out.println(" " + removedTask); - System.out.println(" Look at that! You've got " + remainingTasksCount + " tasks left to juggle!"); - System.out.println(separator); - } - - public void showError(SparkleException e) { - System.out.println(separator); - System.out.println(e.getMessage()); - System.out.println(separator); - } - - public void showExitMessage() { - System.out.print(separator); - System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); - System.out.println(separator); - } - + System.out.println(separator); + } + + /** + * Displays a message confirming that a task has been added. + * + * @param task The task that was added. + * @param taskCount The total number of tasks after adding the new task. + */ + public void showTaskAdded(Task task, int taskCount) { + System.out.print(separator); + System.out.println(" Let's make it fun! I've added this task:"); + System.out.println(" " + task); + System.out.println( + " Looks like you've got " + taskCount + " tasks in your list~ Better get moving!"); + System.out.println(separator); + } + + /** + * Displays a message confirming that a task has been marked as done. + * + * @param task The task that was marked as done. + */ + public void showMarkTaskDone(Task task) { + System.out.println(separator); + System.out.println(" Boom! Task's done and dusted~"); + System.out.println(" " + task); + System.out.println(separator); + } + + /** + * Displays a message confirming that a task has been marked as undone. + * + * @param task The task that was marked as undone. + */ + public void showMarkTaskUndone(Task task) { + System.out.println(separator); + System.out.println(" Not done yet, but it's still on the radar!"); + System.out.println(" " + task); + System.out.println(separator); + } + + /** + * Displays a message confirming that a task has been deleted. + * + * @param removedTask The task that was deleted. + * @param remainingTasksCount The number of remaining tasks after deletion. + */ + public void showTaskDeleted(Task removedTask, int remainingTasksCount) { + System.out.println(separator); + System.out.println(" Got it! Poof! This task is gone:"); + System.out.println(" " + removedTask); + System.out.println( + " Look at that! You've got " + remainingTasksCount + " tasks left to juggle!"); + System.out.println(separator); + } + + /** + * Displays an error message. + * + * @param e The exception containing the error message. + */ + public void showError(SparkleException e) { + System.out.println(separator); + System.out.println(e.getMessage()); + System.out.println(separator); + } + + /** Displays the exit message. */ + public void showExitMessage() { + System.out.print(separator); + System.out.println(" See you around, Stelle~ Try to stay out of trouble next time!"); + System.out.println(separator); + } } diff --git a/src/main/java/sparkle/exception/SparkleException.java b/src/main/java/sparkle/exception/SparkleException.java index db6249a64..f2f4a3406 100644 --- a/src/main/java/sparkle/exception/SparkleException.java +++ b/src/main/java/sparkle/exception/SparkleException.java @@ -1,7 +1,9 @@ +/** Represents exceptions specific to the Sparkle application. */ package sparkle.exception; public class SparkleException extends Exception { + /** Defines different types of errors that can occur in Sparkle. */ public enum ErrorType { EMPTY_TASK_DESCRIPTION, UNKNOWN_COMMAND, @@ -9,10 +11,23 @@ public enum ErrorType { INVALID_FORMAT } + /** + * Constructs a new SparkleException with the specified error type and details. + * + * @param type The type of error encountered. + * @param details Additional details about the error. + */ public SparkleException(ErrorType type, String details) { super(generateMessage(type, details)); } + /** + * Generates an error message based on the given error type and details. + * + * @param type The type of error. + * @param details Additional details about the error. + * @return A formatted error message. + */ private static String generateMessage(ErrorType type, String details) { switch (type) { case EMPTY_TASK_DESCRIPTION: diff --git a/src/main/java/sparkle/task/Deadline.java b/src/main/java/sparkle/task/Deadline.java index 91ee06443..19cf7120c 100644 --- a/src/main/java/sparkle/task/Deadline.java +++ b/src/main/java/sparkle/task/Deadline.java @@ -2,7 +2,12 @@ import sparkle.exception.SparkleException; +/** + * Represents a deadline task that has a specified deadline time. Inherits from the Task class and + * includes functionality for handling deadlines. + */ public class Deadline extends Task { + // Field to store the deadline time protected String by; public Deadline(String description, String by) { @@ -15,11 +20,24 @@ public Deadline(String description, boolean isDone, String by) { this.by = by; } + /** + * Converts the deadline task into a string format suitable for saving to a file. + * + * @return A string representation of the deadline in a format suitable for storage. + */ @Override public String toFileFormat() { return "D | " + super.toFileFormat() + " | " + by; } + /** + * Creates a Deadline object from a string array formatted for file loading. + * + * @param parts A string array containing deadline data in the format [type, done, description, + * by]. + * @return A Deadline object initialized with the data from the array. + * @throws SparkleException If the input data is in an invalid format. + */ public static Deadline fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 4) { throw new SparkleException( @@ -28,6 +46,13 @@ public static Deadline fromFileFormat(String[] parts) throws SparkleException { return new Deadline(parts[2], parts[1].equals("1"), parts[3]); } + /** + * Returns a string representation of the deadline task, including its description and deadline + * time. + * + * @return A string representation of the deadline task in the format "[D][description] (by: + * [deadline])". + */ @Override public String toString() { return "[D]" + super.toString() + " (by: " + by + ")"; diff --git a/src/main/java/sparkle/task/Event.java b/src/main/java/sparkle/task/Event.java index 311da9813..4a95f0e7d 100644 --- a/src/main/java/sparkle/task/Event.java +++ b/src/main/java/sparkle/task/Event.java @@ -2,6 +2,10 @@ import sparkle.exception.SparkleException; +/** + * Represents a deadline task that has a specified deadline time. Inherits from the Task class and + * includes functionality for handling start and end times + */ public class Event extends Task { protected String from; protected String to; @@ -18,6 +22,13 @@ public Event(String description, boolean isDone, String from, String to) { this.to = to; } + /** + * Creates an Event object from a file format string array. + * + * @param parts The string array representing event data. + * @return The Event object created from the data. + * @throws SparkleException If the data is in an invalid format. + */ public static Event fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 4) { throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Event data"); @@ -30,10 +41,20 @@ public static Event fromFileFormat(String[] parts) throws SparkleException { return new Event(parts[2], parts[1].equals("1"), fromTo[0], fromTo[1]); } + /** + * Converts the event to a format suitable for saving to a file. + * + * @return The event data as a string for file storage. + */ public String toFileFormat() { return "E | " + super.toFileFormat() + " | " + from + "-" + to; } + /** + * Returns a string representation of the event. + * + * @return A string representation of the event with start and end times. + */ @Override public String toString() { return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; diff --git a/src/main/java/sparkle/task/Task.java b/src/main/java/sparkle/task/Task.java index 80de38f2e..3ae27f7bb 100644 --- a/src/main/java/sparkle/task/Task.java +++ b/src/main/java/sparkle/task/Task.java @@ -2,20 +2,42 @@ import sparkle.exception.SparkleException; +/** + * Represents a task with a description and completion status. This class provides functionality for + * marking a task as done or undone, converting it to and from a file format, and retrieving the + * task's string representation. + */ public class Task { protected String description; protected boolean isDone; + /** + * Constructs a Task object with the specified description. The task is initially marked as not + * done. + * + * @param description A brief description of the task. + */ public Task(String description) { this.description = description; this.isDone = false; } + /** + * Constructs a Task object with the specified description and completion status. + * + * @param description A brief description of the task. + * @param isDone A boolean indicating whether the task is marked as done. + */ public Task(String description, boolean isDone) { this.description = description; this.isDone = isDone; } + /** + * Returns the status icon of the task, representing whether the task is done or not. + * + * @return A string representing the task's completion status ("X" for done, " " for undone). + */ public String getStatusIcon() { return (isDone ? "X" : " "); } @@ -28,10 +50,22 @@ public void markAsUndone() { this.isDone = false; } + /** + * Converts the Task object into a string format suitable for saving to a file. + * + * @return A string representation of the task in a format suitable for storage. + */ public String toFileFormat() { return (isDone ? "1" : "0") + " | " + description; } + /** + * Creates a Task object from a string array formatted for file loading. + * + * @param parts A string array containing task data in the format [type, done, description]. + * @return A Task object initialized with the data from the array. + * @throws SparkleException If the input data is in an invalid format. + */ public static Task fromFileFormat(String[] parts) throws SparkleException { char type = parts[0].charAt(0); @@ -49,6 +83,11 @@ public static Task fromFileFormat(String[] parts) throws SparkleException { } } + /** + * Returns a string representation of the task, including its status and description. + * + * @return A string representation of the task in the format "[status] description". + */ @Override public String toString() { return "[" + getStatusIcon() + "] " + description; diff --git a/src/main/java/sparkle/task/Todo.java b/src/main/java/sparkle/task/Todo.java index 9b3ff70ad..ee215c971 100644 --- a/src/main/java/sparkle/task/Todo.java +++ b/src/main/java/sparkle/task/Todo.java @@ -2,20 +2,42 @@ import sparkle.exception.SparkleException; +/** + * Represents a Todo task with a description and completion status. Inherits from the Task class and + * includes functionality for handling Todo tasks. + */ public class Todo extends Task { public Todo(String description) { super(description); } + /** + * Constructs a Todo object with the specified description. The task is initially marked as not + * done. + * + * @param description A brief description of the task. + */ public Todo(String description, boolean isDone) { super(description, isDone); } + /** + * Converts the Todo task into a string format suitable for saving to a file. + * + * @return A string representation of the Todo task in a format suitable for storage. + */ @Override public String toFileFormat() { return "T | " + super.toFileFormat(); } + /** + * Creates a Todo object from a string array formatted for file loading. + * + * @param parts A string array containing Todo data in the format [type, done, description]. + * @return A Todo object initialized with the data from the array. + * @throws SparkleException If the input data is in an invalid format. + */ public static Todo fromFileFormat(String[] parts) throws SparkleException { if (parts.length < 3) { throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, "Corrupted Todo data"); @@ -23,6 +45,12 @@ public static Todo fromFileFormat(String[] parts) throws SparkleException { return new Todo(parts[2], parts[1].equals("1")); } + /** + * Returns a string representation of the Todo task, including its description and completion + * status. + * + * @return A string representation of the Todo task in the format "[T][description]". + */ @Override public String toString() { return "[T]" + super.toString(); From 1e9da454cc35b45c66ea7f96eec4616e17a6d69b Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 22:35:43 +0800 Subject: [PATCH 41/43] Fix error --- src/main/java/sparkle/core/TaskList.java | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/sparkle/core/TaskList.java b/src/main/java/sparkle/core/TaskList.java index 24b629bcf..8d191f3f7 100644 --- a/src/main/java/sparkle/core/TaskList.java +++ b/src/main/java/sparkle/core/TaskList.java @@ -91,22 +91,22 @@ public ArrayList getTasks() { * * @return The number of tasks. */ - - public ArrayList findTasks(String keyword) { - ArrayList matchingTasks = new ArrayList<>(); - for (Task task : tasks) { - if (task.getDescription().toLowerCase().contains(keyword.toLowerCase())) { - matchingTasks.add(task); - } - } - return matchingTasks; + public ArrayList findTasks(String keyword) { + ArrayList matchingTasks = new ArrayList<>(); + for (Task task : tasks) { + if (task.getDescription().toLowerCase().contains(keyword.toLowerCase())) { + matchingTasks.add(task); + } } -  /** + return matchingTasks; + } + + /** * Returns the number of tasks in the list. * * @return The number of tasks. */ - public int size() { - return tasks.size(); - } + public int size() { + return tasks.size(); + } } From 331551228c13866f5f3cd624c57aef99aa0ae1e0 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 22:54:24 +0800 Subject: [PATCH 42/43] Add UserGuide --- docs/README.md | 148 +++++++++++++++++++++--- src/main/java/sparkle/core/Sparkle.java | 52 ++++----- 2 files changed, 160 insertions(+), 40 deletions(-) diff --git a/docs/README.md b/docs/README.md index 47b9f984f..b6edfc0ba 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,30 +1,150 @@ -# Duke User Guide +# Sparkle User Guide -// Update the title above to match the actual product name +![Sparkle User Guide Image](https://act-upload.hoyoverse.com/event-ugc-hoyowiki/2024/02/25/127094529/00a75fdab753a244ab93b56d7a53819e_1128020071342605456.png?x-oss-process=image%2Fformat%2Cwebp) -// Product screenshot goes here +## Introduction +Sparkle is a task management chatbot that helps you keep track of your tasks in a fun and interactive way! -// Product intro goes here +## Features -## Adding deadlines +### Adding ToDos +You can add a todo task using the following command: -// Describe the action and its outcome. +**Command:** `todo TASK_NAME` -// Give examples of usage +**Example:** +``` +todo Read a book +``` + +**Expected Output:** +``` + Let's make it fun! I've added this task: + [T][ ] Read a book + Looks like you've got X tasks in your list~ Better get moving! +``` + +### Adding Deadlines +You can add a deadline task using the following command: + +**Command:** `deadline TASK_NAME /by DEADLINE` + +**Example:** +``` +deadline Submit assignment /by Sunday 11:59PM +``` + +**Expected Output:** +``` + Let's make it fun! I've added this task: + [D][ ] Submit assignment (by: Sunday 11:59PM) + Looks like you've got X tasks in your list~ Better get moving! +``` + +### Adding Events +You can add an event task using the following command: -Example: `keyword (optional arguments)` +**Command:** `event TASK_NAME /from START_TIME /to END_TIME` -// A description of the expected outcome goes here +**Example:** +``` +event Team meeting /from Monday 2PM /to Monday 4PM +``` + +**Expected Output:** +``` + Let's make it fun! I've added this task: + [E][ ] Team meeting (from: Monday 2PM to: Monday 4PM) + Looks like you've got X tasks in your list~ Better get moving! +``` + +### Listing Tasks +You can view all your tasks by using: + +**Command:** `list` +**Expected Output:** ``` -expected output + Here are the tasks in your list~ + 1. [T][ ] Read a book + 2. [D][ ] Submit assignment (by: Sunday 11:59PM) + 3. [E][ ] Team meeting (from: Monday 2PM to: Monday 4PM) ``` -## Feature ABC +### Marking a Task as Done +You can mark a task as done using: + +**Command:** `mark TASK_NUMBER` + +**Example:** +``` +mark 1 +``` + +**Expected Output:** +``` + Boom! Task's done and dusted~ + [T][X] Read a book +``` -// Feature details +### Unmarking a Task +You can unmark a task using: +**Command:** `unmark TASK_NUMBER` -## Feature XYZ +**Example:** +``` +unmark 1 +``` + +**Expected Output:** +``` + Not done yet, but it's still on the radar! + [T][ ] Read a book +``` + +### Finding Tasks +You can search for tasks that match a specific keyword using the following command: + +**Command:** `find KEYWORD` + +**Example:** +``` +find assignment +``` +**Expected Output:** +``` + Here are the tasks that match your search~ + 1. [D][ ] Submit assignment (by: Sunday 11:59PM) + +``` + + +### Deleting a Task +You can delete a task using: + +**Command:** `delete TASK_NUMBER` + +**Example:** +``` +delete 2 +``` + +**Expected Output:** +``` + Got it! Poof! This task is gone: + [D][ ] Submit assignment (by: Sunday 11:59PM) + Look at that! You've got X tasks left to juggle! +``` + +### Exiting Sparkle +You can exit the program using: + +**Command:** `bye` + +**Expected Output:** +``` + See you around, Stelle~ Try to stay out of trouble next time! +``` -// Feature details \ No newline at end of file +**Enjoy using Sparkle!** \ No newline at end of file diff --git a/src/main/java/sparkle/core/Sparkle.java b/src/main/java/sparkle/core/Sparkle.java index e4689ada1..c1565da6d 100644 --- a/src/main/java/sparkle/core/Sparkle.java +++ b/src/main/java/sparkle/core/Sparkle.java @@ -1,19 +1,16 @@ package sparkle.core; +import java.util.ArrayList; +import java.util.Scanner; +import sparkle.exception.SparkleException; import sparkle.task.Deadline; import sparkle.task.Event; import sparkle.task.Task; import sparkle.task.Todo; -import sparkle.exception.SparkleException; - -import java.util.ArrayList; -import java.util.Scanner; /** - * This class represents the main logic of the Sparkle application, which - * manages tasks. - * It interacts with the user, processes commands, and updates the task list - * accordingly. + * This class represents the main logic of the Sparkle application, which manages tasks. It + * interacts with the user, processes commands, and updates the task list accordingly. */ public class Sparkle { @@ -22,9 +19,9 @@ public class Sparkle { private TaskList tasks; /** - * Initializes the Sparkle application with the given file path. - * It sets up the UI, storage, and loads the task list from the specified file. - * If loading the tasks fails, it initializes an empty task list. + * Initializes the Sparkle application with the given file path. It sets up the UI, storage, and + * loads the task list from the specified file. If loading the tasks fails, it initializes an + * empty task list. * * @param filePath The file path to load the tasks from. */ @@ -42,10 +39,8 @@ public Sparkle(String filePath) { } /** - * Runs the Sparkle application, continuously accepting user input, processing - * commands, - * and displaying relevant information. The application exits when the user - * types the "bye" command. + * Runs the Sparkle application, continuously accepting user input, processing commands, and + * displaying relevant information. The application exits when the user types the "bye" command. */ public void run() { ui.showLogo(); @@ -79,7 +74,8 @@ public void run() { break; case "todo": if (details.isEmpty()) { - throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); + throw new SparkleException( + SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Todo"); } tasks.addTask(new Todo(details)); ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); @@ -90,7 +86,8 @@ public void run() { } String[] deadlineParts = details.split(" /by ", 2); if (deadlineParts.length < 2) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, "Need a /by time! Or do you plan to finish it... never?"); } tasks.addTask(new Deadline(deadlineParts[0].trim(), deadlineParts[1].trim())); @@ -98,15 +95,19 @@ public void run() { break; case "event": if (details.isEmpty()) { - throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Event"); + throw new SparkleException( + SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Event"); } String[] eventParts = details.split(" /from ", 2); if (eventParts.length < 2 || !eventParts[1].contains(" /to ")) { - throw new SparkleException(SparkleException.ErrorType.INVALID_FORMAT, - "Oops! You forgot the time slots! Gotta add both /from and /to, or this show ain't starting!"); + throw new SparkleException( + SparkleException.ErrorType.INVALID_FORMAT, + "Oops! You forgot the time slots! Gotta add both /from and /to, or this show" + + " ain't starting!"); } String[] timeParts = eventParts[1].split(" /to ", 2); - tasks.addTask(new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); + tasks.addTask( + new Event(eventParts[0].trim(), timeParts[0].trim(), timeParts[1].trim())); ui.showTaskAdded(tasks.getTasks().get(tasks.size() - 1), tasks.size()); break; case "delete": @@ -116,9 +117,9 @@ public void run() { break; case "find": if (details.isEmpty()) { - throw new SparkleException(SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Find"); + throw new SparkleException( + SparkleException.ErrorType.EMPTY_TASK_DESCRIPTION, "Find"); } - // findコマンドに基づき、キーワードでタスクを検索 ArrayList matchingTasks = tasks.findTasks(details); ui.showMatchingTasks(matchingTasks); break; @@ -135,8 +136,7 @@ public void run() { } /** - * The entry point of the Sparkle application. It initializes the application - * with the file path + * The entry point of the Sparkle application. It initializes the application with the file path * and starts the application by calling the `run()` method. * * @param args Command-line arguments (not used). @@ -144,4 +144,4 @@ public void run() { public static void main(String[] args) { new Sparkle("data/sparkle.txt").run(); } -} \ No newline at end of file +} From 202fb3a44f9a970d3c906929dd38ee31f159b3d6 Mon Sep 17 00:00:00 2001 From: Ayu Date: Fri, 14 Mar 2025 23:00:47 +0800 Subject: [PATCH 43/43] Update Readme --- README.md | 176 ++++++++++++++++++++++++++++++++++++------- test_jar/sparkle.jar | Bin 16975 -> 19667 bytes 2 files changed, 150 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index af0309a9e..b6edfc0ba 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,150 @@ -# Duke project template - -This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. - -## Setting up in Intellij - -Prerequisites: JDK 17, update Intellij to the most recent version. - -1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first) -1. Open the project into Intellij as follows: - 1. Click `Open`. - 1. Select the project directory, and click `OK`. - 1. If there are any further prompts, accept the defaults. -1. Configure the project to use **JDK 17** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
- In the same dialog, set the **Project language level** field to the `SDK default` option. -1. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: - ``` - Hello from - ____ _ - | _ \ _ _| | _____ - | | | | | | | |/ / _ \ - | |_| | |_| | < __/ - |____/ \__,_|_|\_\___| - ``` - -**Warning:** Keep the `src\main\java` folder as the root folder for Java files (i.e., don't rename those folders or move Java files to another folder outside of this folder path), as this is the default location some tools (e.g., Gradle) expect to find Java files. +# Sparkle User Guide + +![Sparkle User Guide Image](https://act-upload.hoyoverse.com/event-ugc-hoyowiki/2024/02/25/127094529/00a75fdab753a244ab93b56d7a53819e_1128020071342605456.png?x-oss-process=image%2Fformat%2Cwebp) + +## Introduction +Sparkle is a task management chatbot that helps you keep track of your tasks in a fun and interactive way! + +## Features + +### Adding ToDos +You can add a todo task using the following command: + +**Command:** `todo TASK_NAME` + +**Example:** +``` +todo Read a book +``` + +**Expected Output:** +``` + Let's make it fun! I've added this task: + [T][ ] Read a book + Looks like you've got X tasks in your list~ Better get moving! +``` + +### Adding Deadlines +You can add a deadline task using the following command: + +**Command:** `deadline TASK_NAME /by DEADLINE` + +**Example:** +``` +deadline Submit assignment /by Sunday 11:59PM +``` + +**Expected Output:** +``` + Let's make it fun! I've added this task: + [D][ ] Submit assignment (by: Sunday 11:59PM) + Looks like you've got X tasks in your list~ Better get moving! +``` + +### Adding Events +You can add an event task using the following command: + +**Command:** `event TASK_NAME /from START_TIME /to END_TIME` + +**Example:** +``` +event Team meeting /from Monday 2PM /to Monday 4PM +``` + +**Expected Output:** +``` + Let's make it fun! I've added this task: + [E][ ] Team meeting (from: Monday 2PM to: Monday 4PM) + Looks like you've got X tasks in your list~ Better get moving! +``` + +### Listing Tasks +You can view all your tasks by using: + +**Command:** `list` + +**Expected Output:** +``` + Here are the tasks in your list~ + 1. [T][ ] Read a book + 2. [D][ ] Submit assignment (by: Sunday 11:59PM) + 3. [E][ ] Team meeting (from: Monday 2PM to: Monday 4PM) +``` + +### Marking a Task as Done +You can mark a task as done using: + +**Command:** `mark TASK_NUMBER` + +**Example:** +``` +mark 1 +``` + +**Expected Output:** +``` + Boom! Task's done and dusted~ + [T][X] Read a book +``` + +### Unmarking a Task +You can unmark a task using: + +**Command:** `unmark TASK_NUMBER` + +**Example:** +``` +unmark 1 +``` + +**Expected Output:** +``` + Not done yet, but it's still on the radar! + [T][ ] Read a book +``` + +### Finding Tasks +You can search for tasks that match a specific keyword using the following command: + +**Command:** `find KEYWORD` + +**Example:** +``` +find assignment +``` +**Expected Output:** +``` + Here are the tasks that match your search~ + 1. [D][ ] Submit assignment (by: Sunday 11:59PM) + +``` + + +### Deleting a Task +You can delete a task using: + +**Command:** `delete TASK_NUMBER` + +**Example:** +``` +delete 2 +``` + +**Expected Output:** +``` + Got it! Poof! This task is gone: + [D][ ] Submit assignment (by: Sunday 11:59PM) + Look at that! You've got X tasks left to juggle! +``` + +### Exiting Sparkle +You can exit the program using: + +**Command:** `bye` + +**Expected Output:** +``` + See you around, Stelle~ Try to stay out of trouble next time! +``` + +**Enjoy using Sparkle!** \ No newline at end of file diff --git a/test_jar/sparkle.jar b/test_jar/sparkle.jar index 18d828dd7138e12f3d6d35a47cb2ef62b782454a..8882e63012cdb2a1694e66057c32acaf22cd284d 100644 GIT binary patch literal 19667 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 literal 16975 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 M{IQ~ZuD`zhKa1e_1poj5