forked from mneedham01/CSC120-FinalProject
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Game.java
646 lines (564 loc) · 23.6 KB
/
Game.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
import java.util.Objects;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.HashSet;
import java.util.Set;
import com.google.common.graph.*;
import java.util.Timer;
import java.util.TimerTask;
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
/*
* Class that keeps track of the cat's status, runs Scanner, and sends input to different room classes
*/
public class Game {
String location;
Item holding;
Item climbedOn;
Boolean haveDrunk;
Boolean haveEaten;
Scanner in;
ImmutableGraph<Room> map;
Kitchen kitchen;
Garden garden;
Bedroom bedroom;
Parlor parlor;
Bathroom bathroom;
Item blanket;
Item windowSeat;
Timer timer;
Integer current;
Boolean readyToNap;
Boolean stuckInBath;
Boolean success;
Integer start;
/*
* Constructor for the game: constructs each room, items within the room, organizes the rooms into a Guava map, and sets up game attributes
*/
public Game(){
//Construct rooms
//kitchen
Kitchen kitchen=new Kitchen("kitchen", "a black-and-white tiled clean kitchen. ",this);
this.kitchen=kitchen;
Item table=new Item("table","A sturdy wooden table", false,false,true,false,true, false,true);
Item milk=new Item("milk","A glass of milk",false,true,false,false,false,true,false);
table.addChild(milk);
milk.addParent(table);
this.kitchen.addItem(table);
this.kitchen.addItem(milk);
//garden
Garden garden=new Garden("garden","a lovely enclosed garden space with lots of flowers and a light breeze. ",this);
this.garden=garden;
Item pond=new Item("pond","A stone pond in the center filled with water",false, false, true, false, true, false, true);
Item fish=new Item("fish","Appetizing koi fish swimming lazily", true, false, false, false, false, true, false);
pond.addChild(fish);
fish.addParent(pond);
this.garden.addItem(pond);
this.garden.addItem(fish);
//bedroom
Bedroom bedroom= new Bedroom("bedroom", "a spacious yet cozy bedroom. ",this);
this.bedroom=bedroom;
Item bed=new Item("bed","A large bed with a blanket on top of it",false,false,true,false,true,false,true);
Item blanket=new Item("blanket","A cozy handmade afghan blanket",false,false, false,true,false, true,false);
this.blanket=blanket;
bed.addChild(blanket);
this.blanket.addParent(bed);
Item dresser=new Item("dresser","A handsome chestnut dresser filled with woolen sweaters",false,false,true,false,true,false,false);
this.bedroom.addItem(bed);
this.bedroom.addItem(blanket);
this.bedroom.addItem(dresser);
//parlor
Parlor parlor=new Parlor("parlor", "a homey parlor room. ",this);
this.parlor=parlor;
Item windowSeat=new Item("window seat","A cozy yet bare window seat drenched in sunlight",false,false,true, false,true,false,false);
Item couch=new Item("couch","a plump green corduroy couch",false,false,true,false,true,false,false);
this.windowSeat=windowSeat;
this.parlor.addItem(windowSeat);
this.parlor.addItem(couch);
//bathroom
Bathroom bathroom= new Bathroom("bathroom", "a tiled and clean bathroom. ",this);
this.bathroom=bathroom;
Item bathtub=new Item("bathtub","a large clawfoot bathtub",false,false,true,false,false,false,false);
Item toilet=new Item("toilet","a toilet with water inside",false,false,true,false,true,false,true);
Item water=new Item("water", "cool, clean refreshing water in the toilet",false,true,false,false,false,true,false);
toilet.addChild(water);
water.addParent(toilet);
this.bathroom.addItem(bathtub);
this.bathroom.addItem(toilet);
this.bathroom.addItem(water);
//Build graph
ImmutableGraph<Room> house = GraphBuilder.undirected()
.<Room>immutable()
.putEdge(this.kitchen,this.bedroom)
.putEdge(this.kitchen,this.garden)
.putEdge(this.kitchen,this.parlor)
.putEdge(this.parlor,this.bedroom)
.putEdge(this.bedroom,this.bathroom)
.build();
//set the house to this.map
this.map=house;
//set the current location to kitchen
this.location=kitchen.getName();
//set current statuses
this.holding=null;
this.climbedOn=null;
this.haveDrunk=false;
this.haveEaten=false;
//start integer for timing out
this.current=0;
//start ready to nap boolean
this.readyToNap=false;
//start stuck in bath boolean
this.stuckInBath=false;
//start the success boolean
this.success=false;
//get start time of game
this.start=getTimeSeconds();
}
/*
* Method to print out strings with a delay in between each character
* @param: String toPrint
*/
public void slowPrint(String toPrint) {
for (int i = 0; i<toPrint.length(); i++) {
char c = toPrint.charAt(i);
System.out.print(c);
try {
TimeUnit.MILLISECONDS.sleep(17);
}
catch (Exception e) {
}
}
System.out.println("");
}
/*
* Method to check whether the cat can nap yet or not
* @returns: boolean
*/
public boolean canNap(){
//Ways to check if canNap() is working right
// System.out.println("parlor: "+ this.location.equals("parlor"));
// System.out.println("drink: "+this.haveDrunk);
// System.out.println("eat: "+this.haveEaten);
// if(Objects.nonNull(this.holding)){
// System.out.println("hold: "+this.holding.equals(this.blanket));
// }
// if(Objects.nonNull(this.climbedOn)){
// System.out.println("climb: "+this.climbedOn.equals(this.windowSeat));
// }
if(Objects.nonNull(this.holding)&&Objects.nonNull(this.climbedOn)){
if(this.location.equals("parlor")&& this.haveDrunk && this.haveEaten && this.holding.equals(this.blanket) && this.climbedOn.equals(this.windowSeat)){
return true;
}
else{
return false;
}
}
else{
return false;
}
}
/*
* Method to print out the status of the cat: the time left, whether it can nap yet or not.
*/
public void printNapStatus(){
String currentTime=this.timeConvert(this.current=getTimeSeconds()-this.start);
System.out.println("\nIt is currently: "+currentTime+" PM. Remember, you need to take a nap before 7:00 PM!");
if(this.haveEaten){
this.slowPrint("* You have eaten.");
} else{
this.slowPrint("* You have NOT YET eaten.");
}
if(this.haveDrunk){
this.slowPrint("* You have drunk something.");
}else{
this.slowPrint("* You have NOT YET drunk something.");
}
if(Objects.nonNull(this.holding)){
if(this.holding.equals(this.blanket)){
this.slowPrint("* You are holding a blanket to sleep on.");
}
}else{
this.slowPrint("* You are NOT YET holding a blanket to sleep on.");
}
if(this.location.equals("parlor")&&this.climbedOn.equals(this.windowSeat)){
this.slowPrint("* You are in a sunny spot to sleep.");
}else{
this.slowPrint("* You are NOT YET in a sunny spot to sleep.");
}
}
/*
* Method that returns a list of neighbors based on the current room
* @param: current Room
* @returns: Array list of neighbors
*/
public ArrayList<Room> getNeighbors(Room current){
Set<Room> setOfNeighbors= new HashSet<Room>();
ArrayList<Room> listOfNeighbors= new ArrayList<Room>();
setOfNeighbors=map.adjacentNodes(current);
for (Room r: setOfNeighbors){
listOfNeighbors.add(r);
}
return listOfNeighbors;
}
/*
* Method that prints a list of neighbors
* @param: current Room
*/
public void printNeighbors(Room current){
for (Room r : this.getNeighbors(current)){
this.slowPrint("the "+r.getName()+" [go to the "+r.getName()+"]");
}
}
/*
* Method that checks if a string is a room
* @param: String room
* @returns: boolean
*/
public boolean isARoom(String room){
if (room.equals("bathroom") || room.equals("bedroom") || room.equals("garden")|| room.equals("parlor")||room.equals("kitchen")){
return true;
}else{
return false;
}
}
/*
* Method that returns a room given a corresponding string
* @param: String name
* @returns: Room
*/
public Room turnNameToRoom(String name){
if(name.equals("kitchen")||name.equals("Kitchen")){
return this.kitchen;
}
if(name.equals("bathroom")||name.equals("Bathroom")){
return this.bathroom;
}
if(name.equals("bedroom")||name.equals("Bedroom")){
return this.bedroom;
}
if(name.equals("garden")||name.equals("Garden")){
return this.garden;
}
if (name.equals("parlor")||name.equals("Parlor")){
return this.parlor;
}
//as to not throw an error
else{
return this.kitchen;
}
}
/*
* Getter for this.location
*/
public String getLocation(){
return this.location;
}
/*
* Getter for this.climbedOn
*/
public Item getClimbedOn(){
return this.climbedOn;
}
/*
* Getter for this.haveDrunk
*/
public Boolean getHaveDrunk(){
return this.haveDrunk;
}
/*
* Getter for this.getHaveEaten
*/
public Boolean getHaveEaten(){
return this.haveEaten;
}
/*
* Setter for this.climbedOn
*/
public void changeClimbedOn(Item i){
this.climbedOn=i;
}
/*
* Setter for this.haveEaten
*/
public void changeHaveEaten(Boolean b){
this.haveEaten=b;
}
/*
* Setter for this.haveDrunk
*/
public void changeHaveDrunk(Boolean b){
this.haveDrunk=b;
}
/*
* Setter for this.changeHolding
*/
public void changeHolding(Item i){
this.holding=i;
}
/*
* Setter for this.stuckInBath
*/
public void changeStuckInBath(Boolean b){
this.stuckInBath=b;
}
/*
* Setter for this.success
*/
public void changeSuccess(Boolean b){
this.success=b;
}
/*
* Method to get the current time in secodns format
*/
public Integer getTimeSeconds(){
//getting current time
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
//turn it into HH:mm:ss format
String nowDtf=dtf.format(now);
Integer hours=60*60*Integer.parseInt(nowDtf.split(":")[0]);
Integer minutes=60*Integer.parseInt(nowDtf.split(":")[1]);
Integer seconds=Integer.parseInt(nowDtf.split(":")[2]);
//find total seconds
Integer time=hours+minutes+seconds;
return time;
}
/*
* Method to convert the time in seconds to the game time
* @param: int i (usually time elapsed)
* @returns: String
*/
public String timeConvert(int i){
//pass in the time elapsed from the start of the game in seconds
//the total game is 300 sec in human time, 7 hours in cat time (7*60*60=25,200 sec)
//convert to cat time
int sec=i*(25200/300);
//Get the total hours passed
int num=60*60;
int hour=sec/num;
//if the hour is 0, change to 12
if(hour==0){
hour=12;
}
//Get the leftover number of minutes
int min=sec/60;
//Initialize leftover min
int leftoverMin=0;
//Find the leftover amount of minutes
for (int j = 0; j<10; j++) {
//if we have overshot
if(j*60>min){
//then do the previous one
leftoverMin=min-(j-1)*60;
break;
}
//if it's still under, continue
else{
continue;
}
}
//If the leftover min is less than 10
if(leftoverMin<10){
return hour+":"+"0"+leftoverMin;
}
else{
return hour+":"+leftoverMin;
}
}
/*
* Method to play the game. Prints out instructions, starts a scanner, maintains a while loop sending the responses to room classes while game is being played
*/
public void play(){
System.out.println("\n"+"----------------------------------------------------------------------------------------------------------------------------------");
this.slowPrint("Welcome! In this game, you are a cat in a house searching for the best place to take a nap. In order to nap, you must...\n");
this.slowPrint("* have eaten");
this.slowPrint("* have drunk something");
this.slowPrint("* have a blanket to sleep on");
this.slowPrint("* be in direct sunlight\n");
this.slowPrint("But be careful! Time is running out-- the sun is setting, and you have to get a good nap in before the sunset\n\n");
this.slowPrint("Right now, it is 12 pm. The sun is going to set at 7 pm. Cat time is different than human time (nine lives and all), so you will get warnings throughout the game of the time.");
this.slowPrint("If you fail to nap before sunset, you will lose the game :(");
System.out.println("------------------------------------------------------------------------------------------------------------------------------------");
this.slowPrint("\nIn this house, there is: ");
this.slowPrint(this.kitchen.getDescription());
this.slowPrint(this.garden.getDescription());
this.slowPrint(this.parlor.getDescription());
this.slowPrint(this.bedroom.getDescription());
this.slowPrint(this.bathroom.getDescription()+"\n");
System.out.println("------------------------");
System.out.println("| | bathroom |");
System.out.println("| parlor |-------- |");
System.out.println("| |");
System.out.println("|------- | |");
System.out.println("| | bedroom |");
System.out.println("| kitchen |");
System.out.println("| | |");
System.out.println("|----------------------|");
System.out.println("");
System.out.println(" garden ");
this.slowPrint("\nRight now, you are in the kitchen. \n\n"+this.kitchen.lookAround());
this.slowPrint("There are doors connecting to: ");
this.printNeighbors(this.turnNameToRoom(this.location));
System.out.println();
in=new Scanner(System.in);
//initialize
this.current=getTimeSeconds();
//create Boolean for end of game
Boolean gameGoing=(this.start-this.current<300);
while(gameGoing && !this.readyToNap && !this.stuckInBath){
//reset success
this.success=false;
System.out.println("");
Room locationAsRoom=this.turnNameToRoom(this.location);
this.slowPrint("What would you like to do?");
System.out.print(">>> ");
String response=in.nextLine();
//First, try to parse to see if we need to change this.location
//Turn response into an array list of words
ArrayList<String> wordList = new ArrayList<String>();
for(String word : response.split(" ")) {
wordList.add(word);
}
//Check if the response is "Help"
if(wordList.get(0).equals("Help")||wordList.get(0).equals("help")){
this.slowPrint("\nRemember, in order to nap, you must: ");
this.slowPrint("* have eaten");
this.slowPrint("* have drunk something");
this.slowPrint("* have a blanket to sleep on");
this.slowPrint("* be in direct sunlight\n");
this.slowPrint("\nTry these commands:");
this.slowPrint("* [Look around]");
this.slowPrint("* [Go to the _____]");
this.slowPrint("* [Climb the _____]");
this.slowPrint("* [Jump off of the _____]");
this.slowPrint("* [Eat the _____]");
this.slowPrint("* [Drink the _____]");
continue;
}
//Check that the response is more than one word
if(wordList.size()<2){
this.slowPrint("\nYour response should be more than one word. Try saying 'Go to' a room or an item.");
continue;
}
try{
//get words from response
String word1=wordList.get(0);
String word2=wordList.get(1);
String word3=wordList.get(2);
String word4=wordList.get(3);
boolean word1IsGo=word1.equals("Go")||word1.equals("go");
//Check if the response is "Go to the *room*"
if (word1IsGo && word2.equals("to") && word3.equals("the")&&this.isARoom(word4)){
//Make array list with all the neighbors for the current room
ArrayList<Room> neighbors=this.getNeighbors(locationAsRoom);
//If the fourth word IS a neighbor to the current room
if(neighbors.contains(this.turnNameToRoom(word4))){
//if they are not climbed onto something
if(Objects.isNull(this.climbedOn)){
//Change the location to the fourth word in the response
this.location=word4;
locationAsRoom=this.turnNameToRoom(this.location);
//Print update
this.slowPrint("\nRight now, you are in "+locationAsRoom.getDescription()+locationAsRoom.lookAround());
this.slowPrint("There are doors connecting to: ");
//Print neighbors
this.printNeighbors(this.turnNameToRoom(this.location));
//Reset current time & canNap (restarting while loop)
this.current=getTimeSeconds();
gameGoing=(this.current-this.start<300);
this.readyToNap=this.canNap();
continue;
}
else{
//Reset current time & canNap (restarting while loop)
this.current=getTimeSeconds();
gameGoing=(this.current-this.start<300);
this.readyToNap=this.canNap();
this.slowPrint("\nYou need to [jump off of the "+this.climbedOn.getName()+"] before you can leave the room.");
continue;
}
}
//If the fourth word is NOT a neighbor
else{
//if they are not climbed onto something
if(Objects.isNull(this.climbedOn)){
//if the location is already the location
if(this.location.equals(word4)){
this.slowPrint("\nYou are already at the "+word4+".");
//Reset current time & canNap (restarting while loop)
this.current=getTimeSeconds();
gameGoing=(this.current-this.start<300);
this.readyToNap=this.canNap();
continue;
}
else{
this.slowPrint("\nThere is not a door from the "+this.location+" to the "+ word4+". The "+this.location+" connects to: ");
this.printNeighbors(locationAsRoom);
//Reset current time & canNap (restarting while loop)
this.current=getTimeSeconds();
gameGoing=(this.current-this.start<300);
this.readyToNap=this.canNap();
continue;
}
}
else{
this.slowPrint("\nYou need to [jump off of the "+this.climbedOn.getName()+"] before you can leave the room. Additionally, there is not a door from the "+this.location+" to the "+ word3+". The "+this.location+" connects to: ");
this.printNeighbors(locationAsRoom);
//Reset current time & canNap (restarting while loop)
this.current=getTimeSeconds();
gameGoing=(this.current-this.start<300);
this.readyToNap=this.canNap();
continue;
}
}
}
} catch (Exception e){
}
//If the current location is a room, send the response to that class
if (this.location.equals("kitchen")){
this.kitchen.conversation(wordList);
}
if(this.location.equals("garden")){
this.garden.conversation(wordList);
}
if(this.location.equals("bedroom")){
this.bedroom.conversation(wordList);
}
if(this.location.equals("bathroom")){
this.bathroom.conversation(wordList);
}
if(this.location.equals("parlor")){
this.parlor.conversation(wordList);
}
//reset current time & boolean
this.current=getTimeSeconds();
gameGoing=(this.current-this.start<300);
//call canNap to update situation
this.readyToNap=this.canNap();
//If the program has NOT parsed the response (even if it didn't work), it sends out a general error message
if(this.success==false){
this.slowPrint("\nThat is not a valid command. Try these: ");
this.slowPrint("* [Look around]");
this.slowPrint("* [Go to the _____]");
this.slowPrint("* [Climb the _____]");
this.slowPrint("* [Jump off of the _____]");
this.slowPrint("* [Eat the _____]");
this.slowPrint("* [Drink the _____]");
this.slowPrint("* [Help]");
}
}
if(this.canNap()){
this.slowPrint("\nSNOOOOZE!!!! Yay! You have found something to eat, something to drink, a blanket, and a sunny spot and can now take a well-deserved nap.");
this.slowPrint("GAME OVER.");
}
if(!gameGoing){
this.slowPrint("\nThe sun has set. The room is filled with pink light. You didn't nap, but nightfall is coming and you'll have a wonderful deep sleep.");
this.slowPrint("GAME OVER.");
}
if(this.stuckInBath){
this.slowPrint("\nGAME OVER.");
}
}
}