-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathModel.java
More file actions
1019 lines (918 loc) · 36.7 KB
/
Model.java
File metadata and controls
1019 lines (918 loc) · 36.7 KB
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
//Pictionary
//Programmers: Nicholas Ching / Ryan Song / Erin Hu
//Project: ICS4U CPT
//NETWORKING:
//6000 - MAIN COMMUNICATIONS
//General Format: DesignationID#, ActionID#, IP, Param1, Param2, Param3, Param4
//DesignationID 0 = Intended for Server
//DesignationID 1 = Intended for Clients
//Server Intended Messages
//Initial Connection: 0, 0, IP, ClientName
//Chat Telemetry: 0, 1, IP, Message
//Object Choice Telemetry: 0, 2, IP, Object
//Drawing Telemetry: 0, 3, IP, PosX, PosY, BrushSize, BrushColor
//Client Intended Messages
//Lobby Player Info Ping: 1, 0, IP, PlayerNames[]
//Chat Telemetry: 1, 1, IP, FormattedMessage (with player name)
//Round Intitalization1 (Choosing): 1, 2, IP, RoundsPlayed, DrawerIP, ObjectstoChoose[]
//Round Initializaton Telemetry: 1, 3, IP, TimeRemaining
//Round Initialization2 (Done Choosing): 1, 4, IP, Object.charlength
//Drawing Telemetry: 1, 5, IP, PosX, PosY, BrushSize, BrushColor
//Game Telemetry: 1, 6, IP, TimeRemaining
//Score Update Telemetry: 1, 7, IP, PlayerScores[][]
//Round Completion: 1, 8, IP, Object
//Round Initializaton Telemetry: 1, 9, IP, TimeRemaining
//Score Update - Post Round: 1, 10, IP, FormattedPlayerScores[]
//Object Transmission - Object Not Chosen: 1, 11, IP, Object
//Theme Transmission: 1, 12, IP, Theme
//6001 - INITIAL SERVER CONNECTION
//Server Ping: IP, ServerName, PlayerCount
//SERVER STORAGE:
//Client Details: IP, Name, Points, Answered
import java.io.*;
import javax.swing.*;
/**
* Pictionary Model
* This class deals with the data to play pictionary<br>
* It loads data from word list files into arrays<br>
* It has methods to control server messaging and score data
* <p>
*
* @author Nicholas Ching, Ryan Song, Erin Hu
* @version 1.0.0
* @since 2024-01-21
*/
public class Model{
//Properties
/** Provides access to methods for UX graphics */
View theView;
//Game Settings
/** Time duration when drawer is choosing object to draw */
int intPreRoundDuration = 15000;
/** Time duration when drawer is drawing and other players are guessing */
int intRoundDuration = 90000;
/** Time duration to display correct word after drawing */
int intPostRoundDuration = 5000;
/** Total number of drawing turns */
int intRounds = 5;
/** Number of points for guessing corectly */
int intAnsScore = 50;
//Shared Properties
/** Indicates whether host or client is connected*/
boolean blnConnected = false;
/** Indicates whether user is host or client */
boolean blnHost;
/** Indicates whether game has started */
boolean blnGameStarted = false;
/** Player's username */
String strUsername;
/** Message received*/
String strIncomingSplit[];
/** Chosen theme for drawing */
String strTheme;
/** Round number */
int intRound;
/** Indicates whether player is the drawer*/
boolean blnDrawing;
/** Options for objects that the drawer will draw*/
String strChoiceObjects[];
/** Object that the drawer chooses to draw */
String strObject;
/** Length of object name*/
int intObjectLength;
/** Stores drawing data temporarily for view to retrieve*/
int intTempDraw[] = new int[4];
/** Stores incoming chat message data temporarily for view to retrieve*/
String strTempMessage;
//Server Properties
/** Socket for host*/
SuperSocketMaster HostSocket;
/** Thread for broadcasting IP*/
Thread broadcastIP = new Thread(new broadcastIP(this));
/** List of players */
String strPlayerList[][];
/** Temporarily stores the list of players for it to be resorted */
String strPlayerTemp[][];
/** Stores the 8 themes from themes text file */
String strThemes[] = new String[8];
/** Stores objects from the selected theme file */
String strObjects[];
/** Stores the IP address of the drawer */
String strDrawer;
/** Timer used to ping data to clients periodically */
Timer pingTimer;
/** Timer used for object selection containing a special method that allows you to retrieve time remaining*/
SuperTimer preRoundTimer;
/** Timer used for drawer to draw object */
SuperTimer roundTimer;
/** Timer used to display the correct object after drawing */
SuperTimer postRoundTimer;
//Client Only Properties
/** Socket for client */
SuperSocketMaster ClientSocket;
/** IP address of server */
String strServerAddress;
/** Stores list of available servers to join*/
String[][] strServerList = new String[5][3];
/** Thread for detecting servers */
Thread findServer = new Thread(new findServer(this));
/** List of player names*/
String strPlayers[];
/** % of time remaining for player to guess or draw*/
double dblTimePerRemaining;
/** Stores scores temporarily*/
String strTempScores[];
//Server Methods
/** Set up and connect socket after player enters name
* @param strNameField name inputted by user in text field
* @return a boolean of whether the host socket is connected and broadcasting the IP
*/
public boolean initializeHost(String strNameField){
if(!strNameField.equals("") && !strNameField.contains(",")){
strUsername = strNameField;
blnHost = true;
HostSocket = new SuperSocketMaster(6000, theView);
blnConnected = HostSocket.connect();
if(blnConnected){
broadcastIP.start();
pingTimer.start();
strPlayerList = new String[1][4];
strPlayerList[0][0] = HostSocket.getMyAddress();
strPlayerList[0][1] = strUsername;
strPlayerList[0][2] = "00";
}
return blnConnected;
}
else{
return false;
}
}
//BroadcastIP Message Recall
/** Gets the IP address, username, and length of player list
* @return a String with the IP address, username, and length splitted by commas
*/
public String getStatus(){
return HostSocket.getMyAddress()+","+strUsername+","+strPlayerList.length;
}
//Retrieve Player List
/** Gets the player list which includes IP address, username, and score
* @return a 2D String array with IP address, username, and score
*/
public String[][] getPlayerList(){
return strPlayerList;
}
//Load and Retrieve Themes
/** Gets a theme by reading the theme file
* @return a String array with the list of themes
*/
public String[] getThemes(){
int intCount;
InputStream fileRead = this.getClass().getResourceAsStream("Assets/themes.txt");
if(fileRead != null){
try{
BufferedReader themeFile = new BufferedReader(new InputStreamReader(fileRead));
for(intCount = 0; intCount < 8; intCount++){
strThemes[intCount] = themeFile.readLine();
}
themeFile.close();
strTheme = strThemes[0];
}
catch(FileNotFoundException e){
System.out.println("Unfortunately, the themes file has not been found");
}
catch(IOException e){
System.out.println("Theme Loading Failed");
}
}
else{
try{
BufferedReader themeFile = new BufferedReader(new FileReader("Assets/themes.txt"));
for(intCount = 0; intCount < 8; intCount++){
strThemes[intCount] = themeFile.readLine();
}
themeFile.close();
strTheme = strThemes[0];
}
catch(FileNotFoundException e){
System.out.println("Unfortunately, the themes file has not been found");
}
catch(IOException e){
System.out.println("Theme Loading Failed");
}
}
return strThemes;
}
//Theme Selection Handling
/** Determines whether a theme has been selected
* @param intTheme integer indicates which theme has been chosen
* @return a boolean indicating whether the user has chosen a theme
*/
public boolean selectTheme(int intTheme){
if(strThemes[intTheme - 1] != strTheme){
strTheme = strThemes[intTheme - 1];
HostSocket.sendText("1,12,"+HostSocket.getMyAddress()+","+strTheme);
return true;
}
else{
return false;
}
}
//Loading Theme Objects
/** Load objects of a theme from a text file
* @return a boolean of whether objects have been loaded properly
*/
public boolean loadObjects(){
int intCount;
int intObjects = 0;
InputStream fileRead = this.getClass().getResourceAsStream("Assets/"+strTheme);
if(fileRead != null){
try{
BufferedReader objectFile = new BufferedReader(new InputStreamReader(fileRead));
while(objectFile.readLine() != null){
intObjects++;
}
objectFile.close();
fileRead = this.getClass().getResourceAsStream("Assets/"+strTheme);
objectFile = new BufferedReader(new InputStreamReader(fileRead));
strObjects = new String[intObjects];
for(intCount = 0; intCount < intObjects; intCount++){
strObjects[intCount] = objectFile.readLine();
}
return true;
}
catch(FileNotFoundException e){
System.out.println("Unfortunately, the themes file has not been found");
return false;
}
catch(IOException e){
System.out.println("Theme Loading Failed");
return false;
}
}
else{
try{
BufferedReader objectFile = new BufferedReader(new FileReader("Assets/"+strTheme));
while(objectFile.readLine() != null){
intObjects++;
}
objectFile.close();
objectFile = new BufferedReader(new FileReader("Assets/"+strTheme));
strObjects = new String[intObjects];
for(intCount = 0; intCount < intObjects; intCount++){
strObjects[intCount] = objectFile.readLine();
}
return true;
}
catch(FileNotFoundException e){
System.out.println("Unfortunately, the themes file has not been found");
return false;
}
catch(IOException e){
System.out.println("Theme Loading Failed");
return false;
}
}
}
//Get Random Drawer
/** Randomly choose a player to draw
* @return a String of a random player's IP address from the player list
*/
public String getRandDrawer(){
return strPlayerList[(int)(Math.random() * strPlayerList.length)][0];
}
//Get Random Objects
/** Randomly choose two different objects from the object list<br>
* Drawer will have two options to choose from
* @return a String array with two objects
*/
public String[] getRandObjects(){
String strRandObjects[] = new String[2];
strRandObjects[0] = strObjects[(int)(Math.random() * strObjects.length)];
strRandObjects[1] = strObjects[(int)(Math.random() * strObjects.length)];
while(strRandObjects[0].equals(strRandObjects[1])){
strRandObjects[1] = strObjects[(int)(Math.random() * strObjects.length)];
}
return strRandObjects;
}
//Start Game Procedure
/** Starts game if game is able to load objects from the text file<br>
* Sets the round number to 1
* @return a boolean that indicates whether the objects could be loaded
*/
public boolean startGame(){
blnGameStarted = loadObjects();
if(blnGameStarted){
intRound = 1;
pingTimer = new Timer(1000/60, theView);
pingTimer.start();
}
return blnGameStarted;
}
//New Round
/** Choose random drawer and random objects<br>
* Host sends message to clients<br>
* Start timer for the drawer to choose an object
* @return a boolean that indicates whether the host is the drawer
*/
public boolean newRound(){
//Generating a new Drawer and Objects
strDrawer = getRandDrawer();
strChoiceObjects = getRandObjects();
//Informing Clients of Round Start
HostSocket.sendText("1,2,"+HostSocket.getMyAddress()+","+intRound+","+strDrawer+","+String.join(",", strChoiceObjects));
preRoundTimer.start();
//Checking if the Host is the Drawer
if(strDrawer.equals(HostSocket.getMyAddress())){
blnDrawing = true;
return true;
}
else{
blnDrawing = false;
return false;
}
}
//Starting a Round (Drawing)
/** Allows drawer to start drawing<br>
* Displays hint for the guessers<br>
* Sets player points to 0
*/
public void startRound(){
preRoundTimer.stop();
intObjectLength = strObject.length();
int intCount;
for(intCount = 0; intCount < strPlayerList.length; intCount++){
strPlayerList[intCount][3] = "0";
}
HostSocket.sendText("1,4,"+HostSocket.getMyAddress()+","+intObjectLength);
roundTimer.start();
}
//Ending a Round
/** Finishes the drawer's drawing turn<br>
* Gives drawer points based on % of correct guesses
*/
public void endRound(){
roundTimer.stop();
int intCount;
int intCounter = 0;
int intDrawer = -1;
for(intCount = 0; intCount < strPlayerList.length; intCount++){
if(strPlayerList[intCount][3].equals("1")){
intCounter++;
}
if(strPlayerList[intCount][0].equals(strDrawer)){
intDrawer = intCount;
}
}
strPlayerList[intDrawer][2] = ""+(Integer.parseInt(strPlayerList[intDrawer][2]) + (int)(intAnsScore * 2 * (intCounter/(double)(strPlayerList.length - 1))));
HostSocket.sendText("1,8,"+HostSocket.getMyAddress()+","+strObject);
postRoundTimer.start();
}
/** Reset current drawing round for the next drawing round
* @return a boolean that indicates whether there will be a new drawing round
*/
public boolean resetRound(){
postRoundTimer.stop();
//Reset Properties
if(intRound == intRounds){
//Show Leaderboard and Send Client Message
return false;
}
else{
intRound++;
return true;
}
}
//(RE)-Broadcasts Drawing Data to Clients
/** Host sends drawing data to clients
* @param intDrawData integer array for x position, y position, brush size, and brush colour
*/
public void sendDrawData(int intDrawData[]){
HostSocket.sendText("1,5,"+HostSocket.getMyAddress()+","+intDrawData[0]+","+intDrawData[1]+","+intDrawData[2]+","+intDrawData[3]);
}
//(RE)-Broadcasts Chat Data to Clients
/** Host sends messages for drawing guesses and chat
* @param strIP IP address of the host
* @param strChatData a guess or a message sent in the chat
* @return a String formatted according to chat telemetry
*/
public String sendChatData(String strIP, String strChatData){
int intCount;
String strFormattedChatData = "";
for(intCount = 0; intCount < strPlayerList.length; intCount++){
if(strPlayerList[intCount][0].equals(strIP)){
strFormattedChatData = strPlayerList[intCount][1];
break;
}
}
if(strChatData.toLowerCase().contains(strObject.toLowerCase()) && strPlayerList[intCount][3].equals("0") && !strPlayerList[intCount][0].equals(strDrawer)){
strFormattedChatData = strFormattedChatData + " got the right answer";
//Score Increment
strPlayerList[intCount][2] = "" + (Integer.parseInt(strPlayerList[intCount][2]) + intAnsScore);
strPlayerList[intCount][3] = "1";
}
else if(strChatData.toLowerCase().contains(strObject.toLowerCase())){
strFormattedChatData = strFormattedChatData + " is trying to ruin the fun";
}
else{
strFormattedChatData = strFormattedChatData + ": " + strChatData;
}
HostSocket.sendText("1,1,"+HostSocket.getMyAddress()+","+strFormattedChatData);
return strFormattedChatData;
}
//Get Object Choices
/** Gets the choices of objects to draw
* @return a String array with objects to draw
*/
public String[] getObjectChoices(){
return strChoiceObjects;
}
//Get Round Info
/** Gets the round number
* @return an integer of the round number
*/
public int getRound(){
return intRound;
}
//Server Message Handling
/** Manipulates game data depending on the type of message<br>
* Message types are used for initial connection, chat, object choice, and drawing
* @return an integer for the type of message received
*/
public int serverMessageRecieved(){
strIncomingSplit = HostSocket.readText().split(",");
//Message Type 0: Initial Connection
if(strIncomingSplit[1].equals("0")){
System.out.println("The server has accepted a new client, "+strIncomingSplit[3]+", at "+strIncomingSplit[2]);
int intCount;
strPlayerTemp = strPlayerList;
strPlayerList = new String[strPlayerTemp.length + 1][4];
for(intCount = 0; intCount < strPlayerTemp.length; intCount++){
strPlayerList[intCount] = strPlayerTemp[intCount];
}
strPlayerList[strPlayerTemp.length][0] = strIncomingSplit[2];
strPlayerList[strPlayerTemp.length][1] = strIncomingSplit[3];
strPlayerList[strPlayerTemp.length][2] = "00";
}
//Message Type 1: Chat Telemetry
else if(strIncomingSplit[1].equals("1")){
strTempMessage = sendChatData(strIncomingSplit[2], strIncomingSplit[3]);
}
//Message Type 2: Object Choice Telemetry
else if(strIncomingSplit[1].equals("2")){
strObject = strIncomingSplit[3];
startRound();
}
//Message Type 3: Drawing Telemetry
else if(strIncomingSplit[1].equals("3")){
intTempDraw[0] = Integer.parseInt(strIncomingSplit[3]);
intTempDraw[1] = Integer.parseInt(strIncomingSplit[4]);
intTempDraw[2] = Integer.parseInt(strIncomingSplit[5]);
intTempDraw[3] = Integer.parseInt(strIncomingSplit[6]);
sendDrawData(intTempDraw);
}
return Integer.parseInt(strIncomingSplit[1]);
//Split the server message by commas
//Check index 1 for message type
//Within if-statements, trigger appropriate actions
}
//Regular Server Data Pings
/** Sends server data pings regularly
* @param intType type of message
* @return String for the percentage of remaining time if applicable
*/
public String sendPing(int intType){
//Lobby Player Info Ping
if(intType == 0 && strPlayerList != null){
int intCount;
String strEncode1[] = new String[strPlayerList.length];
for(intCount = 0; intCount < strPlayerList.length; intCount++){
strEncode1[intCount] = strPlayerList[intCount][1];
}
HostSocket.sendText("1,0,"+HostSocket.getMyAddress()+","+String.join(",", strEncode1));
}
//Round Initialization Ping
else if(intType == 1){
HostSocket.sendText("1,3,"+HostSocket.getMyAddress()+","+(preRoundTimer.getRemainingTime()*100.0/intPreRoundDuration));
return (preRoundTimer.getRemainingTime()*100.0/intPreRoundDuration)+"";
}
else if(intType == 2){
HostSocket.sendText("1,6,"+HostSocket.getMyAddress()+","+(roundTimer.getRemainingTime()*100.0/intRoundDuration));
return (roundTimer.getRemainingTime()*100.0/intRoundDuration)+"";
}
else if(intType == 3){
HostSocket.sendText("1,9,"+HostSocket.getMyAddress()+","+(postRoundTimer.getRemainingTime()*100.0/intPostRoundDuration));
return (postRoundTimer.getRemainingTime()*100.0/intPostRoundDuration)+"";
}
//Defualt Return
return null;
}
//Score Change Update Ping
/** Provides updated scores after bubble sorting and formatting
* @return a String array with the new score data
*/
public String[] changedScore(){
String strPlayerListTemp[][] = strPlayerList;
String strTemp[] = new String[strPlayerList.length];
int intCount;
int intCount2;
int intScoreAbove;
int intScoreBelow;
//Bubble Sorting Scores
String strTemp2[];
for(intCount = 0; intCount < strPlayerList.length; intCount++){
for(intCount2 = 0; intCount2 < strPlayerList.length - intCount - 1; intCount2++){
intScoreAbove = Integer.parseInt(strPlayerListTemp[intCount2][2]);
intScoreBelow = Integer.parseInt(strPlayerListTemp[intCount2 + 1][2]);
if(intScoreBelow > intScoreAbove){
strTemp2 = strPlayerListTemp[intCount2 + 1];
strPlayerListTemp[intCount2 + 1] = strPlayerListTemp[intCount2];
strPlayerListTemp[intCount2] = strTemp2;
}
}
}
for(intCount = 0; intCount < strPlayerList.length; intCount++){
strTemp[intCount] = strPlayerListTemp[intCount][2]+" PTS: "+strPlayerListTemp[intCount][1];
//Display Edge Buffering
strTemp[intCount] = " " + strTemp[intCount];
}
HostSocket.sendText("1,7,"+HostSocket.getMyAddress()+","+String.join(",", strTemp));
return strTemp;
}
//Check Answer Status
/** Checks if the round is complete<br>
* Checks number of players who have answered<br>
* If everyone other than the drawer has answered, round is complete
* @return boolean to indicate if the round is over
*/
public boolean roundisComplete(){
int intCount;
int intCounter = 0;
for(intCount = 0; intCount < strPlayerList.length; intCount++){
if(strPlayerList[intCount][3].equals("1")){
intCounter++;
}
}
return (intCounter == (strPlayerList.length - 1));
}
//Game End Update Ping
/** Sorts and formats scores when game is over
* @return String array with sorted and formatted scores for each player
*/
public String[] endGamePing(){
String strPlayerListTemp[][] = strPlayerList;
String strTemp[] = new String[strPlayerList.length];
int intCount;
int intCount2;
int intScoreAbove;
int intScoreBelow;
//Bubble Sorting Scores
String strTemp2[];
for(intCount = 0; intCount < strPlayerList.length; intCount++){
for(intCount2 = 0; intCount2 < strPlayerList.length - intCount - 1; intCount2++){
intScoreAbove = Integer.parseInt(strPlayerListTemp[intCount2][2]);
intScoreBelow = Integer.parseInt(strPlayerListTemp[intCount2 + 1][2]);
if(intScoreBelow > intScoreAbove){
strTemp2 = strPlayerListTemp[intCount2 + 1];
strPlayerListTemp[intCount2 + 1] = strPlayerListTemp[intCount2];
strPlayerListTemp[intCount2] = strTemp2;
}
}
}
for(intCount = 0; intCount < strPlayerList.length; intCount++){
strTemp[intCount] = strPlayerListTemp[intCount][2]+" PTS: "+strPlayerListTemp[intCount][1];
//Display Edge Buffering
strTemp[intCount] = " " + strTemp[intCount];
}
HostSocket.sendText("1,10,"+HostSocket.getMyAddress()+","+String.join(",", strTemp));
return strTemp;
}
//Score Updated Check
/** Checks if score is updated
* @return a boolean to indicate if the score was updated
*/
public boolean checkScoreUpdated(){
if(strTempMessage.split(":").length == 1){
return true;
}
else{
return false;
}
}
//Out of Time Send Object
/** Sends the object if there is no more time for the round */
public void outTimeObjectPing(){
HostSocket.sendText("1,11,"+HostSocket.getMyAddress()+","+strObject);
}
//Client Methods
//Initial Client Connection
/** Sets up client connection and looks for broadcasted IP from server
* @param strNameField
* @return boolean to indicate if user entered a name in the name text field
*/
public boolean initializeClient(String strNameField){
if(!strNameField.equals("") && !strNameField.contains(",")){
strUsername = strNameField;
blnHost = false;
findServer.start();
return true;
}
else{
return false;
}
}
//Client Server Selection
/** Sets up and connects client socket
* @param intButton button pressed when the user chooses which server to join
* @return boolean to indicate whether the client is connected
*/
public boolean initializeClientConnection(int intButton){
strServerAddress = strServerList[intButton - 1][0];
System.out.println(strServerAddress);
ClientSocket = new SuperSocketMaster(strServerAddress, 6000, theView);
blnConnected = ClientSocket.connect();
if(blnConnected){
ClientSocket.sendText("0,0,"+ClientSocket.getMyAddress()+","+strUsername);
return true;
}
else{
//Remove the server from the list and update the list to ensure no gaps
//Disconnect the socket
return false;
}
}
//FindServer Server List Update
/** Update list of servers for the player (client) to join
* @param strServerLoad contains the username, IP, player data of servers found
*/
public void updateServerList(String[] strServerLoad){
int intCount = 0;
//PROGRAM TO ALLOW OVERWRITING IF SAME IP IN THE FUTURE
//Check to see if IP Exists and Slots Filled
for(intCount = 0; intCount < 5; intCount++){
if(strServerList[intCount][0] == null){
strServerList[intCount] = strServerLoad;
intCount = 5;
}
else if(strServerList[intCount][0].equals(strServerLoad[0])){
intCount = 5;
}
}
System.out.println("New PARSE");
System.out.println("Server IP: "+strServerList[0][0]+" | Server Name: "+strServerList[0][1]+" | Server Players: "+strServerList[0][2]);
System.out.println("Server IP: "+strServerList[1][0]+" | Server Name: "+strServerList[1][1]+" | Server Players: "+strServerList[1][2]);
System.out.println("Server IP: "+strServerList[2][0]+" | Server Name: "+strServerList[2][1]+" | Server Players: "+strServerList[2][2]);
System.out.println("Server IP: "+strServerList[3][0]+" | Server Name: "+strServerList[3][1]+" | Server Players: "+strServerList[3][2]);
System.out.println("Server IP: "+strServerList[4][0]+" | Server Name: "+strServerList[4][1]+" | Server Players: "+strServerList[4][2]);
if(strServerList[0][0] != null){
theView.updateServerButton(strServerList[0][1]+" | "+strServerList[0][0]+" | "+strServerList[0][2]+" Players", 1);
}
if(strServerList[1][0] != null){
theView.updateServerButton(strServerList[1][1]+" | "+strServerList[1][0]+" | "+strServerList[1][2]+" Players", 2);
}
if(strServerList[2][0] != null){
theView.updateServerButton(strServerList[2][1]+" | "+strServerList[2][0]+" | "+strServerList[2][2]+" Players", 3);
}
if(strServerList[3][0] != null){
theView.updateServerButton(strServerList[3][1]+" | "+strServerList[3][0]+" | "+strServerList[3][2]+" Players", 4);
}
if(strServerList[4][0] != null){
theView.updateServerButton(strServerList[4][1]+" | "+strServerList[4][0]+" | "+strServerList[4][2]+" Players", 5);
}
}
//Client Message Handling
/** Manipulates game data depending on the type of message<br>
* Message types are for lobby, chat, starting rounds, timers, and scores
* @return integer for type of message received
*/
public int clientMessageRecieved(){
strIncomingSplit = ClientSocket.readText().split(",");
//Message Type 0: Lobby Player Info Ping
if(strIncomingSplit[1].equals("0")){
int intLength = strIncomingSplit.length - 3;
int intCount;
String strDecode[] = new String[intLength];
for(intCount = 0; intCount < intLength; intCount++){
strDecode[intCount] = strIncomingSplit[intCount + 3];
}
strPlayers = strDecode;
}
//Message Type 1: Chat Telemetry
else if(strIncomingSplit[1].equals("1")){
strTempMessage = strIncomingSplit[3];
}
//Message Type 2: Start of a New Round
else if(strIncomingSplit[1].equals("2")){
intRound = Integer.parseInt(strIncomingSplit[3]);
if(strIncomingSplit[4].equals(ClientSocket.getMyAddress())){
blnDrawing = true;
strChoiceObjects = new String[2];
strChoiceObjects[0] = strIncomingSplit[5];
strChoiceObjects[1] = strIncomingSplit[6];
}
else{
blnDrawing = false;
}
}
//Message Type 3: Pre-Round Timer Update Ping
else if(strIncomingSplit[1].equals("3")){
dblTimePerRemaining = Double.parseDouble(strIncomingSplit[3]);
}
//Message Type 4: Start of a Round
else if(strIncomingSplit[1].equals("4")){
intObjectLength = Integer.parseInt(strIncomingSplit[3]);
}
//Message Type 5: Drawing Telemetry
else if(strIncomingSplit[1].equals("5")){
intTempDraw[0] = Integer.parseInt(strIncomingSplit[3]);
intTempDraw[1] = Integer.parseInt(strIncomingSplit[4]);
intTempDraw[2] = Integer.parseInt(strIncomingSplit[5]);
intTempDraw[3] = Integer.parseInt(strIncomingSplit[6]);
}
//Message Type 6: Round Timer Update Ping
else if(strIncomingSplit[1].equals("6")){
dblTimePerRemaining = Double.parseDouble(strIncomingSplit[3]);
}
//Message Type 7: Score Update Telemetry
else if(strIncomingSplit[1].equals("7")){
int intCount;
String strDecode[] = new String[strIncomingSplit.length - 3];
for(intCount = 0; intCount < strIncomingSplit.length - 3; intCount++){
strDecode[intCount] = strIncomingSplit[intCount + 3];
}
strTempScores = strDecode;
}
//Message Type 8: End of a Round
else if(strIncomingSplit[1].equals("8")){
strObject = strIncomingSplit[3];
}
//Message Type 9: Post-Round Timer Update Ping
else if(strIncomingSplit[1].equals("9")){
dblTimePerRemaining = Double.parseDouble(strIncomingSplit[3]);
}
//Message Type 10: Leaderboard Ping
else if(strIncomingSplit[1].equals("10")){
int intCount;
String strDecode[] = new String[strIncomingSplit.length - 3];
for(intCount = 0; intCount < strIncomingSplit.length - 3; intCount++){
strDecode[intCount] = strIncomingSplit[intCount + 3];
}
strTempScores = strDecode;
}
//Message Type 11: Object Selection Out of Time
else if(strIncomingSplit[1].equals("11")){
strObject = strIncomingSplit[3];
}
//Message Type 12: Theme Image Loading
else if(strIncomingSplit[1].equals("12")){
strTheme = strIncomingSplit[3];
}
return Integer.parseInt(strIncomingSplit[1]);
}
//Retrieve Player List
/** Get list of players
* @return String array for player list
*/
public String[] getPlayers(){
return strPlayers;
}
//Retrieve Drawing Status
/** Get drawing status
* @return boolean to indicate whether the user is drawing
*/
public boolean isDrawing(){
return blnDrawing;
}
//Retrieve Time Remaining Percentage
/** Get the percentage of time remaining
* @return double value of the percentage of time remaining
*/
public double getTimeRemPer(){
return dblTimePerRemaining;
}
//Retrieve Player Scores
/** Get player scores
* @return String array of player's scores
*/
public String[] getScores(){
return strTempScores;
}
/** Get chosen theme
* @return String for the chosen theme
*/
public String getTheme(){
return strTheme;
}
//Shared Methods
//Select Object to Draw
/** Allows drawer to choose between two objects to draw
* @param intButton button that the drawer selects
*/
public void choseObject(int intButton){
if(intButton == 1){
strObject = strChoiceObjects[0];
}
else{
strObject = strChoiceObjects[1];
}
if(blnHost){
if(!isDrawing()){
outTimeObjectPing();
}
startRound();
}
else{
ClientSocket.sendText("0,2,"+ClientSocket.getMyAddress()+","+strObject);
}
}
//Send New Drawing Data
/** Send new drawing data
* @param intDrawData drawing data for x position, y position, brush size, and brush colour
*/
public void newDrawData(int intDrawData[]){
if(blnHost){
sendDrawData(intDrawData);
}
else{
ClientSocket.sendText("0,3,"+ClientSocket.getMyAddress()+","+intDrawData[0]+","+intDrawData[1]+","+intDrawData[2]+","+intDrawData[3]);
}
}
//Send Chat Message
/** Send a chat message
* @param strMessage text entered by the user in a text field
* @return boolean to indicate whether the text field is blank
*/
public boolean newMessage(String strMessage){
if(!strMessage.equals("")){
if(blnHost){
strTempMessage = sendChatData(HostSocket.getMyAddress(), strMessage);
}
else{
ClientSocket.sendText("0,1,"+ClientSocket.getMyAddress()+","+strMessage);
}
}
return strMessage.equals("");
}
//Demo Screen
/** Detects whether the user entered their username<br>
* If a username is entered, this will allow them to access the demo
* @param strNameField username entered by the user
* @return boolean to indicate whether the user entered a username
*/
public boolean initializeDemo(String strNameField){
if(!strNameField.equals("")){
strUsername = strNameField;
return true;
}
else{
return false;
}
}
//Retrieve Item Drawing
/** Gets the object that the drawer chose to draw
* @return String of the object that the drawer chose to draw
*/
public String getObject(){
return strObject;
}
//Retrieve Drawing Data
/** Gets drawing data
* @return integer array for x position, y position, brush size, and brush colour
*/
public int[] getDrawingData(){
return intTempDraw;
}
//Retrieve Message Data
/** Gets incoming message data
* @return String with the incoming message data
*/
public String getMessageData(){
return strTempMessage;
}
//Retrieve Object Length
/** Gets the number of characters in the object
* @return integer with the length of the object
*/
public int getObjectLength(){
return intObjectLength;
}
//Retrieve Host Status
/** Gets the host status
* @return boolean to indicate whether the player is the host