-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimonSaysRevisedFinalGame.java
1321 lines (1163 loc) · 50.4 KB
/
SimonSaysRevisedFinalGame.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
Names: Jeffery Hu and Simon Bakan
Date: January 29, 2021.
FileName: SimonSaysRevisedFinalGame.java
Teacher: Ms. Krasteva
Description: This program will execute the traditional Simon Says game that is played on a circle with 4 or 6
colours. The program has the user play the game with key presses using the getChar method of
rtp.
The program starts out with a splash screen of a rotating simon says animation and the title
fading in.
After the splash screen the user is directed to a main menu where they can choose one of 4
options; i for instruction; l to see the leaderboard; c to continue to level and difficulty selection and
then the game; and q to quit and close the screen.
Instructions is a simple screen telling the user how to play and then goes back to the menu
after a key press.
The leader board reads from a file with up to 10 high scores and prints them out on the screen.
It then goes back to the main menu after a key press.
The level selection allows the user to choose a level from one to five using 'w' and 's' to navigate. Once they have decided on a level, they can press 'enter' to
continue to difficulty selection or e to go back to the main menu.
The difficulty selection then allows the user to choose a difficulty of either 4 or 6 colours. It also contains the option
to return to the main menu.
After the level selection the game starts showing the circle with 4 or 6 colours with letters labeled on each colour ('qwas' for 4 colours, 'qweasd' for 6 colours).
The computer first displays the pattern by flashing in order the selected colours. Then, the user must repeat the pattern by pressing the matching letters the selected colours in order.
Each level will start with one flash that the user has to repeat and slowly build up the pattern by one until the user is repeating the whole pattern back.
If the user successfully plays back the full pattern, the win screen will be displayed where the user can return to level
selection (and keep adding to their points) or exit to the menu. If the user loses
the lose screen will be displayed and the user will be taken back to the menu.
If the user has a sufficient score to get onto the leaderboard, the program will ask for their name whenever they exit. This can be in the lose screen or when they decide to exit after beating a level.
To exit, the user must press 'q' at the main menu. This will bring them to the goodbye screen where they can close the program.
Multiple Screens:
1. Splash Screen: The splash screen is used to draw a short animation when the program starts.
2. Main menu: The main menu screen is the centerpiece of program flow. It allows the user to either continue to level selection, view the leaderboard, view the instructions, or exit the program.
3. Instructions: The instructions screen displays the instructions of how the program will work to the user.
4. Leaderboard: The leaderboard screen displays the high score leaderboard in the game.
5. Level Selecion: The level selection screen displays the levels and gets the level the user would like to play.
6. Difficulty Selecion: The difficulty selection screen asks the user to choose between the two difficulties. It also has the option to exit.
6. Display and Get Data Screen: The Display and Get Data Screen will play the pattern on the Simon Says wheel and prompt the user to play it back.
7. Win Screen: If the user successfully plays back the whole pattern, then the win screen will be displayed. The win screen contains a win message and a checkmark.
8. Lose Screen: If the user loses at any point during the playback, the lose screen will be displayed. The lose screen contains a lose message and a sad face.
9. Good Bye Screen: The good bye screen displays a farewell message to the user and prompts them to exit the game.
GlobalVariable Dictionary:
Name | Type | Purpose
-------------------|----------------|--------------------------------------------------------------------------------------------------------
c | Console | Creates an instance of the console class
pattern | char[] | Stores all the characters inside the pattern in the correct order
win | boolean | Stores the value of whether the user has won or lost the level. It will be set to false immediately when/if the user types in the wrong character. It will be set to true as default. It decides if the program displays the win or lose screen, and if the user can continue playing.
level | int | Stores which level the user would like to try
choice | char | Stores where the user wants to go from main menu
endChoice | char | Stores where the user wants to go from the win screen (either continues to level selection or back to main menu)
CORRECTANSPOINTS | final int | Stores the amount of points that will be given for each correct character/colour playback
score | int | Stores the total score during an attempt from the user (will end once the user loses)
levelSelection | char | Stores what the user inputs in the level selection screen (it is also used in the main method so that the user can exit to main menu from level selection)
difficultySelection| char | Stores which difficulty the user would like to try (it is also used in the main method so that the user can exit to main menu from level selection)
Citations:
1. Sorting method taken from "Leson 1-7 Arrays Intro.pdf" lesson sheet by Ms. Krasteva
2. JOptionPane input aquired from https://www.javatpoint.com/java-joptionpane
*/
//Import statements
import java.awt.image.*;
import java.awt.*;
import hsa.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
// The "SimonSaysRevisedFinalGame" class.
public class SimonSaysRevisedFinalGame
{
Console c;
char[] pattern;
boolean win;
int level = 1;
char choice;
char endChoice;
final int CORRECTANSPOINTS = 10;
int score = 0;
char levelSelection;
char difficultySelection;
public SimonSaysRevisedFinalGame () // The constructor
{
c = new Console ("Simon Says"); // Set "Simon Says" as the title of the console window
}
/*
Purpose: The purpose of the splashScreen is to display an animation with the simon says wheel to start off the program. This method will display that screen to introduce and welcome the user to the program.
Local Variable Dictionary:
Name | Type | Purpose
-------------|-------|--------------------------------------------------------------------------------------------------------
x | int | Stores the X coordinate of the Simon Says wheel.
y | int | Stores the Y coordinate of the Simon Says wheel.
incrementX | int | Stores how much further the Simon Says wheel will move left or right during the animation.
incrementY | int | Stores how much further the Simon Says wheel will move up or down during the animation.
arcAngle | int | Stores the base angle for all the arcs making up the colour wheel, which allows the Simon Says wheel spin around as the variable changes.
colourOpacity| int | Stores how transparent the title is so it can fade in.
lightBlue | Color | Stores the light blue colour.
While loops:
1. The first while loop is used to animate the Simon Says wheel so it spins in and bounces off the edge.
a) The try-catch statement is used to slow down the animation.
b) The if statement is used to reverse the direction once it hits the edge.
b) The if else statement is used to animate the Simon Says wheel. Once it hits the correct final position in the middle of the screen, it will break out of the loop and stop animating.
2. The second while loop is used to create the "fading in effect" for the title.
*/
private void splashScreen ()
{
int x = 0;
int y = 0;
int incrementX = 5;
int incrementY = 2;
int arcAngle = 90;
int colourOpacity = 0;
Color lightBlue = new Color (51, 152, 255);
while (true)
{
//Outer black base
c.setColor (Color.black);
c.fillOval (x - 10, y - 10, 200, 200);
c.setColor (Color.red);
c.fillArc (x, y, 180, 180, arcAngle, 90);
c.setColor (Color.blue);
c.fillArc (x, y, 180, 180, (arcAngle + 270), 90);
c.setColor (Color.yellow);
c.fillArc (x, y, 180, 180, (arcAngle + 180), 90);
c.setColor (Color.green);
c.fillArc (x, y, 180, 180, (arcAngle + 90), 90);
//center
c.setColor (Color.black);
c.fillOval (x + 65, y + 65, 50, 50);
try
{
Thread.sleep (45);
}
catch (Exception e)
{
}
if (x == 450)
{
incrementX *= -1;
}
if (x == 230 && incrementX < 0)
{
break;
}
else
{
c.setColor (Color.white);
c.fillOval (x - 10, y - 10, 200, 200);
}
arcAngle += 45;
x += incrementX;
y += incrementY;
}
c.setColor (lightBlue);
c.fillRoundRect (40, 50, 570, 140, 20, 20);
while (true)
{
if (colourOpacity < 100)
{
c.setColor (new Color (51 + (51 * colourOpacity / 100), 152 + (103 * colourOpacity / 100), 255 - (153 * colourOpacity / 100)));
c.setFont (new Font ("Arial", Font.PLAIN, 100));
c.drawString ("Simon Says", 60, 150);
colourOpacity++;
try
{
Thread.sleep (20);
}
catch (Exception e)
{
}
}
else
{
break;
}
}
try
{
Thread.sleep (2000);
}
catch (Exception e)
{
}
}
/*
Purpose: The purpose of the title is to clear the screen and display a background with colours on the edges and a grey rectangle in the middle (as a template for most of the screens).
Local Variable Dictionary:
Name | Type | Purpose
-------------|-------|--------------------------------------------------------------------------------------------------------
x | int[] | Stores the X coordinates for the green triangle on the left of the screen.
y | int[] | Stores the Y coordinates for the green triangle on the left of the screen.
x2 | int[] | Stores the X coordinates for the red triangle on the top of the screen.
y2 | int[] | Stores the Y coordinates for the red triangle on the top of the screen.
x3 | int[] | Stores the X coordinates for the yellow triangle on the right of the screen.
y3 | int[] | Stores the Y coordinates for the yellow triangle on the right of the screen.
x4 | int[] | Stores the X coordinates for the blue triangle on the bottom of the screen.
y4 | int[] | Stores the Y coordinates for the blue triangle on the bottom of the screen.
*/
private void title ()
{
c.clear ();
c.setColor (Color.green);
int x[] = {0, 0, 320, 0};
int y[] = {0, 500, 250, 0};
c.fillPolygon (x, y, 3); // Green triangle on the left of the screen
c.setColor (Color.red);
int x2[] = {0, 640, 320, 0};
int y2[] = {0, 0, 250, 0};
c.fillPolygon (x2, y2, 3); // Red triangle on the top of the screen
c.setColor (Color.yellow);
int x3[] = {640, 640, 320, 640};
int y3[] = {0, 500, 250, 0};
c.fillPolygon (x3, y3, 3); // Yellow triangle on the right of the screen
c.setColor (Color.blue);
int x4[] = {0, 640, 320, 0};
int y4[] = {500, 500, 250, 640};
c.fillPolygon (x4, y4, 3); // Blue triangle on the bottom of the screen
c.setColor (new Color (230, 230, 230));
c.fillRect (10, 8, 620, 484); // Grey rectangle in the background
c.setColor (Color.black);
}
/*
Purpose: The purpose of the mainMenu is to control the flow of the program and to give the user a choice of what they want to do.
While loops:
1. The while loop is a while true loop with a break conditional to error trap the choice so it keeps prompting the user until they enter a valid choice.
Conditional:
1. The conditional is an if else statement that has a condition testing if the user entered character is one of the ones it is looking for. If it is it breaks the loop and if it isnt it throws an error.
Try-catch blocks:
1. The try-catch statement allows the program to throw a custom error when an invalid character is entered to display a JOption pane.
*/
public void mainMenu ()
{
title ();
//title
c.setFont (new Font ("Arial", Font.BOLD, 50));
c.drawString ("Menu:", 250, 80);
c.setFont (new Font ("Arial", Font.PLAIN, 20));
c.drawString ("Press a key to choose what to do:", 50, 130);
c.drawString ("i - See instructions", 50, 190);
c.drawString ("c - Continue to Level Selection", 50, 250);
c.drawString ("l - See leader board", 50, 310);
c.drawString ("q - Quit and close the game", 50, 370);
while (true)
{
try
{
choice = c.getChar ();
if (choice == 'c' || choice == 'C' || choice == 'i' || choice == 'I' || choice == 'l' || choice == 'L' || choice == 'q' || choice == 'Q')
{
break;
}
else
{
throw new IllegalArgumentException ();
}
}
catch (IllegalArgumentException e)
{
JOptionPane.showMessageDialog (null, "Sorry, the value you entered is invalid. Please try again.\npress c to continue.\npress i for instructions\npress l for the leaderboard\npress q to quit", "Error", JOptionPane.ERROR_MESSAGE); // error message
}
}
}
/*
Purpose: The purpose of the instructions method is to display the instructions on how the game will work to the user.
*/
public void instructions ()
{
title ();
//title
c.setFont (new Font ("Arial", Font.PLAIN, 50));
c.drawString ("Instructions:", 180, 80);
c.setFont (new Font ("Arial", Font.PLAIN, 20));
c.drawString ("The video game of Simon Says is a game of memory. A circle", 50, 130);
c.drawString ("with 4 or 6 colours will be displayed. It will do a pattern of", 50, 160);
c.drawString ("flashes, turning white and you will have to repeat the sequence", 50, 190);
c.drawString ("with the appropriate key that is labeled on the colour.", 50, 220);
c.drawString ("It will go up in length each round and you will get", 50, 250);
c.drawString ("points for each correct character repeat. To beat", 50, 280);
c.drawString ("a level, you need to repeat the full pattern. If you win,", 50, 310);
c.drawString ("you can choose to play again to continue racking up points.", 50, 340);
c.drawString ("If you lose, your points will reset. Beating a level will", 50, 370);
c.drawString ("result in an extra point bonus. Good luck!", 50, 400);
c.drawString ("Press any key to continue.", 50, 430);
c.getChar ();
}
/*
Purpose: The purpose of the leaderboard method is to display the leaderboard for the game. It will read the names and scores on the Simon Says High Scores file and display it in the console window.
Local Variable Dictionary:
Name | Type | Purpose
-------------|----------------|--------------------------------------------------------------------------------------------------------
input | BufferedReader | Helps to read lines in the file
line | int | Keeps track of the line number the buffered reader is reading.
nameScore | String | Stores a string with the name of the person on the leader board with a " - " and their score.
runThrough | String | Stores how much further the Simon Says wheel will move up or down during the animation.
y | int | Stores the y coordinate of each highscore on the leaderboard.
end | boolean | Stores how transparent the title is so it can fade in.
inputFile | String | Stores the name of the input file.
Try-catch statement:
1. The try catch statement is used to try and read the names and high scores on the Simon Says High Scores file.
While loops:
1. The while loop is used to keep reading names and scores from the file until it reads null, in which case it will stop reading.
If-else statements:
1. The first if else statement is used to make sure that what is read is not null. If it is, end is set to true and the loop will stop.
2. The second if else statement is used to see if what is read on the line is the name or high score. If it is the name, then it will store it in variable nameScore. If it is the score, then it will add it onto the name in nameScore and display it on the console window.
*/
public void leaderBoard ()
{
BufferedReader input;
int line = 0;
String nameScore = " ";
String runThrough;
int y = 180;
boolean end = false;
String inputFile = "SimonSaysHighScores.txt";
title ();
c.setFont (new Font ("Arial", Font.PLAIN, 50));
c.drawString ("Leaderboard:", 180, 80);
c.setFont (new Font ("Arial", Font.PLAIN, 20));
c.drawString ("The leaderboard displays the top 10 scores. If your score is", 50, 120);
c.drawString ("higher than the 10th largest score, it will be displayed here.", 50, 150);
try
{
input = new BufferedReader (new FileReader (inputFile));
while (end != true)
{
runThrough = input.readLine ();
line += 1;
if (runThrough == null)
{
end = true;
}
else
{
if (line % 2 == 1)
{
nameScore += runThrough;
}
else if (line % 2 == 0)
{
nameScore = nameScore + " ----- " + runThrough;
c.drawString (line / 2 + ". " + nameScore, 50, y);
nameScore = " ";
y += 30;
}
}
}
}
catch (IOException e)
{
}
c.drawString ("Press any key to exit.", 50, y);
c.getChar ();
}
/*
Purpose: The purpose of the getLevel method is to ask the user for the level which determines the number of flashes in the pattern.
While loops:
1. The first while loop keeps the user inputting characters to change the level until the user presses enter to continue or e to exit.
Conditionals:
1. The first conditional is an if else if statement that evaluates the key pressed.
a) an if statement that sends a JOption pane if the charactered entered is not one of the ones expected.
b) an else if statement that subtracts one from level if w is pressed.
c) an else if statement that adds one to level if s is pressed.
d) an else if statement that breaks which will send the user to menu if e is pressed.
e) an else if statement that breaks which will send the user to the game if the enter key is pressed.
2. an if statement that will set level to 1 if it gets to 6 to loop back up to the top.
2. an if statement that will set level to 5 if it gets to 0 to loop to the bottom.
*/
public void getLevel ()
{
title ();
//title
c.setFont (new Font ("Arial", Font.PLAIN, 50));
c.drawString ("Level Selection:", 150, 80);
//explanation
c.setFont (new Font ("Arial", Font.PLAIN, 20));
c.drawString ("Press enter to select the level.", 50, 130);
c.drawString ("1 - Level 1 (up to 4 flashes)", 50, 160);
c.drawString ("2 - Level 2 (up to 6 flashes)", 50, 190);
c.drawString ("3 - Level 3 (up to 8 flashes)", 50, 220);
c.drawString ("4 - Level 4 (up to 10 flashes)", 50, 250);
c.drawString ("5 - Level 5 (up to 12 flashes)", 50, 280);
c.drawString ("*Use 'w' and 's' to move up or down the levels.", 50, 310);
c.drawString ("*Press 'e' to return to the main menu.", 50, 340);
while (true)
{
//star
c.setColor (Color.black);
c.fillStar (10, 140 + (level - 1) * 30, 25, 25);
levelSelection = c.getChar ();
//background
c.setColor (new Color (230, 230, 230));
c.fillStar (10, 140 + (level - 1) * 30, 25, 25);
if (levelSelection != 'w' && levelSelection != 'W' && levelSelection != 's' && levelSelection != 'S' && levelSelection != 10 && levelSelection != 10 && levelSelection != 'e' && levelSelection != 'E')
{
JOptionPane.showMessageDialog (null, "Sorry, the value you entered is invalid. Please enter either 'w', 's', 'e', or 'enter'.\n\n", "Error", JOptionPane.ERROR_MESSAGE); // error message
}
else if (levelSelection == 'w' || levelSelection == 'W')
{
level -= 1;
}
else if (levelSelection == 's' || levelSelection == 'S')
{
level += 1;
}
else if (levelSelection == 'e' || levelSelection == 'E')
{
break;
}
else if (levelSelection == 10 || levelSelection == 10)
{
break;
}
if (level == 6)
{
level = 1;
}
if (level == 0)
{
level = 5;
}
}
}
/*
Purpose: The purpose of the getDifficulty method is to ask the user for the difficulty they want to play at which determines the number of colours in the Simon Says wheel.
While loops:
1. The first while loop keeps prompting the user to input characters until they enter a valid one ('n','h', or 'e').
Conditionals:
1. The first conditional is an if statements that throws an error if the inputted character is not one of the excpected ones.
Try-Catch Blocks:
1. The only try catch block is for the error trapping where a custom error is thrown if the user enters an unexpected character. A JOption pane will be displayed if the user input is invalid.
*/
public void getDifficulty ()
{
title ();
//title
c.setFont (new Font ("Arial", Font.PLAIN, 50));
c.drawString ("Difficulty Selection:", 110, 80);
//explanation
c.setFont (new Font ("Arial", Font.PLAIN, 20));
c.drawString ("Choose your difficulty. Hard will get you 50% more points:", 50, 130);
c.drawString ("Press n for normal - 4 colours", 50, 190);
c.drawString ("Press h for hard - 6 colours", 50, 250);
c.drawString ("Press e to exit to the main menu.", 50, 310);
while (true)
{
try
{
difficultySelection = c.getChar ();
if (difficultySelection != 'n' && difficultySelection != 'N' && difficultySelection != 'h' && difficultySelection != 'H' && difficultySelection != 'e' && difficultySelection != 'E')
{
throw new IllegalArgumentException ();
}
break;
}
catch (IllegalArgumentException e)
{
JOptionPane.showMessageDialog (null, "Sorry, the value you entered is invalid. Please enter either 'n', 'h', or 'e'.\n\n", "Error", JOptionPane.ERROR_MESSAGE); // error message
}
}
}
/*
Purpose: The purpose of the getPattern method is to get a random pattern for the colour sequence. The length of the pattern will also be taken into account, and will be taken from the parameter.
Local Variable Dictionary:
Name | Type | Purpose
-------------|-------|--------------------------------------------------------------------------------------------------------
size | int | Stores the size of the array.
difficulty | char | Determines if the user wants 4 colours or 6 colours in the pattern.
charRand | int | Stores the random numbers between 1-4 or 1-6 before they are converted into chars
For loop:
1. The for loop is used to keep coming up with random characters (either 'q', 'w', 'a', or 's') until it reaches the required length of the pattern.
If-else statements:
1. The first if else statement is used to see if the program should generate a pattern with 4 letters or 6 letters.
2. The second if else statement is used to take the randomized number and associate it with a character (either 'q', 'w', 'a', or 's', the same number will be associated with the same character each time).
It will then store that character in the given index of the array (creating a pattern).
*/
public void getPattern (int size, char difficulty)
{
int charRand;
c.clear ();
pattern = new char [size];
for (int i = 0 ; i < size ; i++)
{
if (difficulty == 'n' || difficulty == 'N')
{
charRand = (int) (Math.random () * (4) + 1);
}
else
{
charRand = (int) (Math.random () * (6) + 1);
}
if (charRand == 1)
{
pattern [i] = 'q';
}
else if (charRand == 2)
{
pattern [i] = 'w';
}
else if (charRand == 3)
{
pattern [i] = 'a';
}
else if (charRand == 4)
{
pattern [i] = 's';
}
else if (charRand == 5)
{
pattern [i] = 'e';
}
else
{
pattern [i] = 'd';
}
}
}
/*
Purpose: The purpose of the displayAndGetData method is to run the game by displaying the pattern and asking the user to repeat the pattern.
Local Variable Dictionary:
Name | Type | Purpose
-------------|-------|--------------------------------------------------------------------------------------------------------
flashSpeed | int | Tracks the speed of the computer flashes that get faster each round.
print | char | Stores which colour will be the one flashing on the wheel.
m | int | A FOR loop count that is used to track how many flashes of the pattern it is showing.
i | int | A FOR loop count that is used to go through the array and display all the flashes. It also asks for the user input key presses.
Conditional:
1. The first conditional is an if else statement that prints the wheel with 4 or 6 colours depending on the difficulty.
2. The second conditional is an if else statement that either plays the pattern or gets user input playing back the pattern (depending on the loop count).
3. The third conditional is an if statement that error trapps for an invalid entry when the user plays back the sequence. This if-else statement differenciates between 4 colours vs 6 colours, so you cannot enter 'e' or 'd' for 4 colours.
4. The fourth conditional is an if else statement that displays a JOption pane message with the keys that you can press depending on which difficulty it is.
5. The fifth conditional is an if else block that returns if the user got it wrong and adds points to score if they got it right (after calling the black box return method).
6. The sixth conditional is an if else block that adds correctAnsPoints to the user's score if the difficulty is normal or 150% of correctAnsPoints if it is hard difficulty.
7. The seventh conditional is an if else block that controls whether it flashes on a Simon Says wheel with 4 or 6 colours.
8. The eighth conditional is an if else if block that determines which colour to flash (depending on the value of print) for the normal difficulty.
9. The ninth conditional is an if else if block that determines which colour to flash (depending on the value of print) for the hard difficulty.
10. The tenth conditional is an if else statement that pauses for more time between flashes if it is the computer's turn or less if it is the user's.
11. The eleventh conditional statement is an if else statement that determines whether to return the Simon Says wheel to a 4 colour wheel or a 6 colour wheel.
12. The twelfth conditional is an if else if block that returns the sector that was flashed back to its normal colour in the normal dificulty.
13. The thirteenth conditional is an if else if block that returns the sector that was flashed back to its normal colour in the hard dificulty.
For loops:
1. The first for loop is used to increase the length/index that is last read in the pattern each time the loop repeats.
2. The second for loop repeats twice as much as the outer loop counter. The first half of the iterations assign the character (at index of i/the loop count) from the Pattern array to print.
The second half of the iterations get user input which is assigned to print as well. The program displays a flash each time the loop is run depending on the value of print, so it will either flash the pattern or flash what the user inputted. (We decided to use 1 loop to make it more efficient so we don't have to draw the graphics twice)
While loops:
1. The one while loop is used to error trap the user input until they enter a letter that is on the wheel ('q', 'w', 'a', 's', 'e' or 'd').
Try-catch blocks:
1. The first try-catch block is used for a thread sleep before the computer's flash.
2. The second try-catch block is used for a custom error for error trapping the character so if user enters an invalid key it displays an error message.
3. The third try-catch block is used for a thread sleep during the flash so the user can see where it has flashed before it disappears.
*/
public void displayAndGetData ()
{
int flashSpeed = 500;
char print;
title ();
win = true;
//Outer black base
c.setColor (Color.black);
c.fillOval (113, 73, 414, 414);
if (difficultySelection == 'n' || difficultySelection == 'N')
{
//Colours
c.setColor (Color.red);
c.fillArc (130, 90, 380, 380, 0, 90);
c.setColor (Color.blue);
c.fillArc (130, 90, 380, 380, 270, 90);
c.setColor (Color.yellow);
c.fillArc (130, 90, 380, 380, 180, 90);
c.setColor (Color.green);
c.fillArc (130, 90, 380, 380, 90, 90);
//Letters
c.setColor (Color.black);
c.setFont (new Font ("Arial", Font.PLAIN, 50));
c.drawString ("Q", 220, 210);
c.drawString ("W", 370, 210);
c.drawString ("A", 220, 380);
c.drawString ("S", 370, 380);
}
else
{
// 6 colours
//Colours
c.setColor (Color.red);
c.fillArc (130, 90, 380, 380, 0, 60);
c.setColor (Color.blue);
c.fillArc (130, 90, 380, 380, 300, 60);
c.setColor (Color.pink);
c.fillArc (130, 90, 380, 380, 240, 60);
c.setColor (Color.yellow);
c.fillArc (130, 90, 380, 380, 180, 60);
c.setColor (Color.green);
c.fillArc (130, 90, 380, 380, 120, 60);
c.setColor (Color.orange);
c.fillArc (130, 90, 380, 380, 60, 60);
//Letters
c.setColor (Color.black);
c.setFont (new Font ("Arial", Font.PLAIN, 50));
c.drawString ("Q", 190, 235);
c.drawString ("W", 296, 170);
c.drawString ("E", 405, 235);
c.drawString ("A", 195, 355);
c.drawString ("S", 304, 425);
c.drawString ("D", 403, 355);
}
//center
c.setColor (Color.black);
c.fillOval (270, 230, 100, 100);
for (int m = 1 ; m <= pattern.length ; m++)
{
flashSpeed -= 25;
for (int i = 0 ; i < m * 2 ; i++)
{
c.setColor (new Color (230, 230, 230));
c.fillRect (50, 15, 580, 45);
//Score
c.setColor (Color.black);
c.setFont (new Font ("Arial", Font.PLAIN, 20));
c.drawString ("Score: " + score, 20, 40);
if (i < m)
{
c.setFont (new Font ("Arial", Font.PLAIN, 30));
c.drawString ("Pay Attention to the Pattern!", 150, 50);
try
{
Thread.sleep (flashSpeed);
}
catch (Exception e)
{
}
print = pattern [i];
}
else
{
c.setFont (new Font ("Arial", Font.PLAIN, 30));
c.drawString ("Play Back the Pattern!", 170, 50);
while (true)
{
try
{
print = c.getChar (); // Collect user input
if ((print != 'q' && print != 'Q' && print != 'w' && print != 'W' && print != 's' && print != 'S' && print != 'a' && print != 'A') && ((difficultySelection == 'n' || difficultySelection == 'N') || print != 'e' && print != 'E' && print != 'd' && print != 'D'))
{
throw new IllegalArgumentException (); // Custom exception
}
break;
}
catch (IllegalArgumentException E)
{
if (difficultySelection == 'n' || difficultySelection == 'N')
{
JOptionPane.showMessageDialog (null, "Error! Please press either 'q', 'w', 's', or 'a'.\n\n", "Error", JOptionPane.ERROR_MESSAGE); // error message
}
else
{
JOptionPane.showMessageDialog (null, "Error! Please press either 'q', 'w', 's', 'a', 'e', or 'd'.\n\n", "Error", JOptionPane.ERROR_MESSAGE); // error message
}
}
}
win = patternIsEqual (print, i - m);
if (win == false)
{
return;
}
else
{
if (difficultySelection == 'n' || difficultySelection == 'N')
{
score += CORRECTANSPOINTS;
}
else
{
score += CORRECTANSPOINTS * 1.5;
}
}
}
if (difficultySelection == 'n' || difficultySelection == 'N')
{
if (print == 'q' || print == 'Q')
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 90, 90);
}
else if (print == 'w' || print == 'W')
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 0, 90);
}
else if (print == 'a' || print == 'A')
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 180, 90);
}
else
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 270, 90);
}
}
else // 6 colours
{
if (print == 'q' || print == 'Q')
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 120, 60);
}
else if (print == 'w' || print == 'W')
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 60, 60);
}
else if (print == 'a' || print == 'A')
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 180, 60);
}
else if (print == 's' || print == 'S')
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 240, 60);
}
else if (print == 'e' || print == 'E')
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 0, 60);
}
else
{
c.setColor (Color.white);
c.fillArc (130, 90, 380, 380, 300, 60);
}
//Colours
}
//center
c.setColor (Color.black);
c.fillOval (270, 230, 100, 100);
try
{
if (i < m)
{
Thread.sleep (flashSpeed);
}
else
{
Thread.sleep (200);
}
}
catch (Exception e)
{
}
c.setFont (new Font ("Arial", Font.PLAIN, 50));
if (difficultySelection == 'n' || difficultySelection == 'N')
{
if (print == 'q' || print == 'Q')
{
c.setColor (Color.green);
c.fillArc (130, 90, 380, 380, 90, 90);
c.setColor (Color.black);
c.drawString ("Q", 220, 210);
}
else if (print == 'w' || print == 'W')
{
c.setColor (Color.red);
c.fillArc (130, 90, 380, 380, 0, 90);
c.setColor (Color.black);
c.drawString ("W", 370, 210);
}
else if (print == 'a' || print == 'A')
{
c.setColor (Color.yellow);
c.fillArc (130, 90, 380, 380, 180, 90);
c.setColor (Color.black);
c.drawString ("A", 220, 380);
}
else
{
c.setColor (Color.blue);
c.fillArc (130, 90, 380, 380, 270, 90);
c.setColor (Color.black);
c.drawString ("S", 370, 380);
}
}
else // 6 colours
{
if (print == 'q' || print == 'Q')
{
c.setColor (Color.green);
c.fillArc (130, 90, 380, 380, 120, 60);
c.setColor (Color.black);
c.drawString ("Q", 190, 235);
}
else if (print == 'w' || print == 'W')
{
c.setColor (Color.orange);
c.fillArc (130, 90, 380, 380, 60, 60);
c.setColor (Color.black);
c.drawString ("W", 296, 170);
}
else if (print == 'a' || print == 'A')
{
c.setColor (Color.yellow);
c.fillArc (130, 90, 380, 380, 180, 60);
c.setColor (Color.black);
c.drawString ("A", 195, 355);
}
else if (print == 's' || print == 'S')
{
c.setColor (Color.pink);
c.fillArc (130, 90, 380, 380, 240, 60);
c.setColor (Color.black);
c.drawString ("S", 304, 425);
}
else if (print == 'e' || print == 'E')
{
c.setColor (Color.red);
c.fillArc (130, 90, 380, 380, 0, 60);
c.setColor (Color.black);
c.drawString ("E", 405, 235);
}
else
{
c.setColor (Color.blue);
c.fillArc (130, 90, 380, 380, 300, 60);
c.setColor (Color.black);
c.drawString ("D", 403, 355);
}
//Colours
}
//center
c.setColor (Color.black);
c.fillOval (270, 230, 100, 100);
}
try
{
Thread.sleep (1000);
}
catch (Exception e)
{
}
}
//Bonus points
score += 50 * level;
}
/*
Purpose: The purpose of the patternIsEqual method is to check if the user input is equal to the specific character in the pattern.
It is run after every character the user enters in displayAndGetData, so every character is checked individually (so that the lose screen appears right when the user enters a wrong input).
It will return true if the user inputted the correct character or false if the user inputted the wrong character.
Local Variable Dictionary:
Name | Type | Purpose
-------------|-------|--------------------------------------------------------------------------------------------------------
input | char | Stores the character the user inputted.
index | int | Provides the index in the array (which stores the pattern) to check the user input against.
If-else statements:
1. The if else statement is used to check the user input against the correct character in the pattern.
*/
private boolean patternIsEqual (char input, int index)
{
if (pattern [index] == input)
{
return true;
}
else
{
return false;
}
}
/*
Purpose: The purpose of the winScreen method is to display a win screen and message and prompt the user to either continue playing Simon Says or exit to main menu.
Local Variable Dictionary:
Name | Type | Purpose
-------------|-------|--------------------------------------------------------------------------------------------------------
darkGreen | Color | Stores the dark green colour.
x | int[] | Provides the x coordinates for all the vertices in the left rectangle (to draw the left side of the check mark).
y | int[] | Provides the y coordinates for all the vertices in the left rectangle (to draw the left side of the check mark).
i | int[] | Provides the x coordinates for all the vertices in the right rectangle (to draw the right side of the check mark).
z | int[] | Provides the y coordinates for all the vertices in the right rectangle (to draw the right side of the check mark).
User input statement:
1. Gets and stores the user input into endChoice to see if the user wants to continue to level selection and keep getting points or if they want to exit to main menu.
*/
public void winScreen ()
{
Color darkGreen = new Color (0, 100, 0);
c.clear ();
title ();
c.setColor (darkGreen);
c.setFont (new Font ("Arial", Font.PLAIN, 40));
c.drawString ("YOU PASSED THE LEVEL!", 70, 90); // Title
c.setFont (new Font ("Arial", Font.PLAIN, 22));
c.drawString ("Press any key to continue back to level selection or 'e' to exit to", 20, 150); // Description
c.drawString ("main menu.", 20, 180);