Updated model
This commit is contained in:
parent
d391c6904a
commit
f9b8903711
119
README.md
119
README.md
|
@ -1,73 +1,82 @@
|
||||||
# itmo-prog-lab-4
|
# itmo-prog-lab-4
|
||||||
## Class Description
|
## Class Description
|
||||||
|
|
||||||
### StoryTeller
|
### Package: `characters`
|
||||||
- The primary class of the application. It establishes the story's framework, incorporating the city, house, and characters, and initiates the storytelling process.
|
- **Character.java**: An abstract class representing a character in the story. Implements `Listenable` and `Conversable` interfaces.
|
||||||
|
- **Connections**: Inherits from `StoryElement` in `model` package. Used by `Child` and `Traveler`.
|
||||||
|
- **Child.java**: Represents child characters in the story, capable of thinking and conversing about story elements.
|
||||||
|
- **Connections**: Inherits from `Character`.
|
||||||
|
- **Traveler.java**: Represents traveler characters in the story, who can tell stories about their adventures.
|
||||||
|
- **Connections**: Inherits from `Character`. Interacts with `Adventure` in `story` package.
|
||||||
|
- **Znayka.java**: A specific implementation of `Traveler`, representing the character Znayka.
|
||||||
|
- **Connections**: Inherits from `Traveler`.
|
||||||
|
|
||||||
### Package: characters
|
### Package: `enums`
|
||||||
- **Character.java**: This abstract class forms the foundation for all character types, implementing `Listenable` and `Conversable` interfaces.
|
- **CharacterType.java**: Defines character types (TRAVELER, CHILD).
|
||||||
- **Child.java**: Represents child characters who listen to and inquire about stories.
|
- **AdventureType.java**: Defines types of adventures (FAMOUS, UNKNOWN).
|
||||||
- **Traveler.java**: Depicts traveler characters who share tales of their adventures.
|
- **LifeType.java**: Defines types of life (NOT_AS_USUAL, AS_USUAL).
|
||||||
- **Znayka.java**: A specialized traveler character with extended capabilities.
|
|
||||||
|
|
||||||
### Package: enums
|
### Package: `exceptions`
|
||||||
- **CharacterType.java**: Enumerates different character types, such as `TRAVELER` and `CHILD`.
|
- **StoryEventException.java**: Custom exception to handle specific story-related errors.
|
||||||
|
- **StoryLogicException.java**: Custom runtime exception for handling logic errors in the story.
|
||||||
|
|
||||||
### Package: interfaces
|
### Package: `interfaces`
|
||||||
- **Listenable.java**: An interface for characters that can listen to stories.
|
- **Interactable.java**: Interface for story elements that can interact.
|
||||||
- **Conversable.java**: An interface for characters that can engage in discussions about specific story subjects.
|
- **Conversable.java**: Interface for characters that can converse.
|
||||||
|
- **Listenable.java**: Interface for characters that can listen.
|
||||||
|
|
||||||
### Package: model
|
### Package: `model`
|
||||||
- **City.java**: Symbolizes a city in the story, featuring a method to simulate life resuming with changes.
|
- **StoryElement.java**: An abstract class representing a story element with a description and metadata.
|
||||||
- **House.java**: Represents a house where characters reside and where storytelling happens.
|
- **Connections**: Parent class for `Location`.
|
||||||
- **StoryElement.java**: An abstract base class for story components like City and House.
|
- **City.java**: Represents a city in the story, managing travelers, children, and houses.
|
||||||
|
- **Connections**: Inherits from `Location`. Aggregates `Traveler`, `Child`, and `House` from `characters` package.
|
||||||
|
- **House.java**: Represents a house in the city, hosting residents and stories.
|
||||||
|
- **Connections**: Inherits from `Location`. Contains `Character` from `characters` package.
|
||||||
|
- **Location.java**: An abstract class representing a location in the story.
|
||||||
|
- **Connections**: Parent class for `City` and `House`.
|
||||||
|
|
||||||
### Package: story
|
### Package: `story`
|
||||||
- **Narrative.java**: Manages a series of story events.
|
- **StoryEvent.java**: Represents an event in the story.
|
||||||
- **StoryContext.java**: Provides the narrative backdrop, linking the city, house, and the main story theme.
|
- **Connections**: Used in `City` from `model` package.
|
||||||
- **StoryEvent.java**: Constitutes individual events within the narrative.
|
- **StoryContext.java**: Provides context for the story elements.
|
||||||
|
- **Connections**: Used in `Adventure` and `House` from `model` package.
|
||||||
|
- **Adventure.java**: Represents an adventure in the story, involving travelers and locations.
|
||||||
|
- **Connections**: Uses `Traveler` from `characters` package, `City` and `House` from `model` package.
|
||||||
|
|
||||||
### Package: exceptions
|
### Main Class
|
||||||
- **StoryException.java**: Handles exceptions specific to the storytelling process.
|
- **StoryTeller.java**: Main class orchestrating the storytelling process. Initializes the story's setting, characters, and events.
|
||||||
- **StoryRuntimeException.java**: Manages runtime exceptions within the story.
|
- **Connections**: Uses instances of `City`, `Traveler`, `House`, `Child`, `Adventure` from the respective packages, and handles exceptions.
|
||||||
|
|
||||||
## Interactions and Configurations
|
|
||||||
|
|
||||||
- **StoryTeller**: Sets up the storytelling environment by creating a city, a house (Znayka's house), and characters (Znayka, Malish, and Malishka), then initiates the storytelling sequence in Znayka's house.
|
|
||||||
- **Character Classes**: Each character type (`Child`, `Traveler`, `Znayka`) interacts uniquely within the narrative. Children listen and pose questions, while travelers focus on recounting their adventures.
|
|
||||||
- **Interfaces**: `Listenable` and `Conversable` are implemented distinctly across character classes, enabling varied behaviors during the storytelling sessions.
|
|
||||||
- **Model Classes**: `City` and `House` form the physical backdrop of the story. The `House` class, in particular, is central to the gathering of characters and the exchange of stories.
|
|
||||||
- **Story Classes**: `StoryContext` connects the narrative's physical and thematic elements. `Narrative` and `StoryEvent` orchestrate the progression and individual occurrences of the story.
|
|
||||||
- **Exception Handling**: The `exceptions` package ensures robust error handling during the storytelling process, with `StoryException` and `StoryRuntimeException` tailored to specific storytelling scenarios.
|
|
||||||
|
|
||||||
|
## Query
|
||||||
|
```
|
||||||
|
На этом знаменитое путешествие Знайки и его товарищей окончилось.
|
||||||
|
Жизнь в Цветочном городе потекла по-старому... хотя нет, нельзя сказать, чтобы совсем по-старому.
|
||||||
|
С тех пор как наши отважные путешественники вернулись домой, в городе только и говорили о них.
|
||||||
|
Все жители, и малыши и малышки, приходили по вечерам к домику Знайки и слушали рассказы путешественников об их жизни в Зеленом городе.
|
||||||
|
```
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
```
|
```
|
||||||
Translating story on Bus 0 Device 0: ID 0x0:JMTek, LLC. USB PnP Audio Device
|
На этом знаменитое путешествие Знайка закончилось.
|
||||||
Translating story on Bus 1 Device 1: ID 0x10101:Creative Technology, Ltd SoundBlaster MP3+
|
Жители Цветочный город собрались вместе, чтобы отпраздновать возвращение путешественников.
|
||||||
Translating story on Bus 2 Device 2: ID 0x20202:Sennheiser Communications USB Headset
|
Путешественники столкнулись с проблемой
|
||||||
Translating story on Bus 3 Device 3: ID 0x30303:Bluetooth Audio Device
|
Путешественники вспомнили о путешествие в Зеленый город
|
||||||
[DEBUG] Story Element Created: Цветочный город
|
|
||||||
[DEBUG] Story Element Created: Домик Знайки
|
|
||||||
[DEBUG] Story Element Created: TRAVELER Знайка
|
|
||||||
[DEBUG] Story Element Created: CHILD Малыш
|
|
||||||
[DEBUG] Story Element Created: CHILD Малышка
|
|
||||||
[DEBUG] Interaction with 'Домик Знайки': Starting evening stories session
|
|
||||||
Жители собираются в Домик Знайки чтобы рассказать истории
|
|
||||||
Все жители, и малыши и малышки, приходили по вечерам к Домик Знайки и слушали рассказы путешественников.
|
|
||||||
Жизнь в Цветочный город потекла по-старому... хотя нет, нельзя сказать, чтобы совсем по-старому.
|
Жизнь в Цветочный город потекла по-старому... хотя нет, нельзя сказать, чтобы совсем по-старому.
|
||||||
Жители собираются в Домик Знайки чтобы рассказать истории
|
С тех пор как наши отважные путешественники Знайка вернулись домой, в городе только и говорили о них.
|
||||||
Знайка рассказывает историю о путешествие в Зеленый город
|
Жители собираются в Дом Знайки чтобы рассказать истории
|
||||||
Малыш слушает историю о путешествия Знайки и спрашивает вопросы о путешествие в Зеленый город
|
Все жители слушают историю о путешествии в путешествие в Зеленый город в Цветочный город
|
||||||
Внезапный флешбенгер
|
И вот, когда все собрались в доме Знайка, Знайка рассказал историю о том, как он путешествие в Зеленый город в Цветочный город
|
||||||
[DEBUG] Interaction with 'Домик Знайки': Внезапный флешбенгер
|
Малыш слушает: Малыш слушает историю о путешествие в Зеленый город и спрашивает вопросы о путешествие в Зеленый город
|
||||||
Малышка слушает историю о путешествия Знайки и спрашивает вопросы о путешествие в Зеленый город
|
Малышка слушает: Малышка слушает историю о путешествие в Зеленый город и спрашивает вопросы о путешествие в Зеленый город
|
||||||
Знайка рассказывает историю о жизнь в Цветочном городе
|
Знайка рассказывает: Знайка умно рассказывает историю о путешествие в Зеленый город
|
||||||
Малыш слушает историю о путешествия Знайки и спрашивает вопросы о жизнь в Цветочном городе
|
и думает: Немного я знаю о городах, но история о путешествие в Зеленый город мне очень понравилась
|
||||||
Малышка слушает историю о путешествия Знайки и спрашивает вопросы о жизнь в Цветочном городе
|
|
||||||
Истории захватывали дух, и каждый вечер собирались всё больше жителей, чтобы слышать новые приключения.
|
Истории захватывали дух, и каждый вечер собирались всё больше жителей, чтобы слушать новые приключения.
|
||||||
Error in storytelling: No stories available to tell.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## UML Diagram
|
## UML Diagram
|
||||||
![UML Diagram](https://new.akarpov.ru/media/files/sanspie/DmZte/diagram.svg "https://new.akarpov.ru/files/YsvFMeuMCbOpfnOlOlyN")
|
![UML Diagram](https://new.akarpov.ru/media/files/sanspie/eNCBb/bebra2.svg "https://new.akarpov.ru/files/GKoEHHkHACqWRrehyNZe")
|
||||||
|
|
||||||
|
## Вывод
|
||||||
|
В ходе выполнения данной лабораторной работы я научился работать с интерфейсами, абстрактными классами, исключениями, локальными классами, анонимными классами.
|
11
lab-3.iml
11
lab-3.iml
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
|
@ -1,69 +1,79 @@
|
||||||
import characters.Character;
|
import enums.AdventureType;
|
||||||
import exceptions.StoryException;
|
import enums.LifeType;
|
||||||
|
import exceptions.StoryEventException;
|
||||||
|
import exceptions.StoryLogicException;
|
||||||
import model.*;
|
import model.*;
|
||||||
import characters.*;
|
import characters.*;
|
||||||
import story.StoryContext;
|
import story.Adventure;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
public class StoryTeller {
|
public class StoryTeller {
|
||||||
public static void main(String[] args) {
|
|
||||||
class DevStoryListener {
|
|
||||||
private int devNum = 0;
|
|
||||||
|
|
||||||
void listenToStory(String device) {
|
|
||||||
System.out.println("Translating story on Bus " + devNum + " Device " + devNum + ": ID " + hashCode(devNum) + ":" + device );
|
|
||||||
devNum++;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String hashCode(int devNum) {
|
|
||||||
return "0x" + Integer.toHexString(devNum * 0x10000 + devNum * 0x100 + devNum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DevStoryListener listener = new DevStoryListener();
|
|
||||||
listener.listenToStory("JMTek, LLC. USB PnP Audio Device");
|
|
||||||
listener.listenToStory("Creative Technology, Ltd SoundBlaster MP3+");
|
|
||||||
listener.listenToStory("Sennheiser Communications USB Headset");
|
|
||||||
listener.listenToStory("Bluetooth Audio Device");
|
|
||||||
|
|
||||||
|
|
||||||
// На этом знаменитое путешествие Знайки и его товарищей окончилось.
|
// На этом знаменитое путешествие Знайки и его товарищей окончилось.
|
||||||
// Жизнь в Цветочном городе потекла по-старому... хотя нет, нельзя сказать, чтобы совсем по-старому.
|
// Жизнь в Цветочном городе потекла по-старому... хотя нет, нельзя сказать, чтобы совсем по-старому.
|
||||||
// С тех пор как наши отважные путешественники вернулись домой, в городе только и говорили о них.
|
// С тех пор как наши отважные путешественники вернулись домой, в городе только и говорили о них.
|
||||||
// Все жители, и малыши и малышки, приходили по вечерам к домику Знайки и слушали рассказы путешественников об их жизни в Зеленом городе.
|
// Все жители, и малыши и малышки, приходили по вечерам к домику Знайки и слушали рассказы путешественников об их жизни в Зеленом городе.
|
||||||
|
public static void main(String[] args) {
|
||||||
// Creating the setting for the story
|
|
||||||
City flowerCity = new City("Цветочный город");
|
|
||||||
House znaykasHouse = new House("Домик Знайки");
|
|
||||||
StoryContext context = new StoryContext(flowerCity, znaykasHouse, "путешествия Знайки");
|
|
||||||
|
|
||||||
// Creating the characters
|
|
||||||
Character znayka = new Znayka();
|
|
||||||
Character malish = new Child("Малыш");
|
|
||||||
Character malishka = new Child("Малышка");
|
|
||||||
|
|
||||||
// Adding characters to Znayka's house
|
|
||||||
znaykasHouse.addResident(znayka);
|
|
||||||
znaykasHouse.addResident(malish);
|
|
||||||
znaykasHouse.addResident(malishka);
|
|
||||||
|
|
||||||
List<String> stories = new ArrayList<>();
|
|
||||||
stories.add("путешествие в Зеленый город");
|
|
||||||
stories.add("жизнь в Цветочном городе");
|
|
||||||
|
|
||||||
znaykasHouse.tellEveningStories(context, stories);
|
|
||||||
stories.clear();
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (stories.isEmpty()) {
|
City city = new City("Цветочный город", LifeType.NOT_AS_USUAL);
|
||||||
throw new StoryException("No stories available to tell.");
|
|
||||||
|
// Create adventurers
|
||||||
|
Traveler znayka = new Znayka();
|
||||||
|
// znayka.addAdventure("Жизнь в Зеленом городе");
|
||||||
|
znayka.returnHome();
|
||||||
|
|
||||||
|
city.addTraveler(znayka);
|
||||||
|
|
||||||
|
// Create house
|
||||||
|
House znaykaHouse = new House("Дом Знайки", znayka, city);
|
||||||
|
|
||||||
|
// Add house to the city.
|
||||||
|
city.addHouse(znaykaHouse);
|
||||||
|
|
||||||
|
// Create children
|
||||||
|
Child child1 = new Child("Малыш");
|
||||||
|
Child child2 = new Child("Малышка");
|
||||||
|
|
||||||
|
// Add children to the city
|
||||||
|
city.addChild(child1);
|
||||||
|
city.addChild(child2);
|
||||||
|
|
||||||
|
// Duplicate creation of City object removed
|
||||||
|
Adventure adventure = new Adventure("путешествие в Зеленый город", AdventureType.FAMOUS, List.of(znayka));
|
||||||
|
adventure.setLocation(city);
|
||||||
|
if (adventure.getLocation() == null) {
|
||||||
|
throw new StoryLogicException("Путешествие не может начаться без указания места");
|
||||||
}
|
}
|
||||||
znaykasHouse.tellEveningStories(context, stories);
|
|
||||||
} catch (StoryException e) {
|
znayka.addAdventure(adventure); // REMOVE ME
|
||||||
System.err.println("Error in storytelling: " + e.getMessage());
|
adventure.end();
|
||||||
|
if (znayka.getAdventures().isEmpty()) {
|
||||||
|
throw new StoryEventException("У Знайки нет приключений");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Celebrate the return of the travelers
|
||||||
|
city.celebrateReturnOfTravelers();
|
||||||
|
|
||||||
|
// Recount a challenging part of Znayka's adventure
|
||||||
|
Adventure.Challenge adventureChallenge = new Adventure.Challenge();
|
||||||
|
adventureChallenge.present();
|
||||||
|
|
||||||
|
// Recall a memorable moment from the adventure
|
||||||
|
Adventure.Memory adventureMemory = adventure.new Memory();
|
||||||
|
adventureMemory.recall();
|
||||||
|
|
||||||
|
city.returnToDailyLife();
|
||||||
|
city.recognizeTravelers();
|
||||||
|
|
||||||
|
znaykaHouse.addResident(child1);
|
||||||
|
znaykaHouse.addResident(child2);
|
||||||
|
znaykaHouse.addResident(znayka);
|
||||||
|
|
||||||
|
|
||||||
|
znaykaHouse.tellEveningStories(adventure);
|
||||||
|
|
||||||
|
} catch (StoryEventException | StoryLogicException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,15 @@ package characters;
|
||||||
import enums.CharacterType;
|
import enums.CharacterType;
|
||||||
import interfaces.Conversable;
|
import interfaces.Conversable;
|
||||||
import interfaces.Listenable;
|
import interfaces.Listenable;
|
||||||
import model.StoryElement;
|
import story.StoryContext;
|
||||||
|
import story.StoryElement;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public abstract class Character extends StoryElement implements Listenable, Conversable {
|
public abstract class Character extends StoryElement implements Listenable, Conversable {
|
||||||
protected CharacterType type;
|
protected CharacterType type;
|
||||||
protected String name;
|
protected String name;
|
||||||
|
protected StoryContext context;
|
||||||
|
|
||||||
public Character(CharacterType type, String name) {
|
public Character(CharacterType type, String name) {
|
||||||
super(type + " " + name);
|
super(type + " " + name);
|
||||||
|
@ -15,16 +19,31 @@ public abstract class Character extends StoryElement implements Listenable, Conv
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Character character) {
|
public void setContext(StoryContext context) {
|
||||||
return this.name.equals(character.name) && this.type.equals(character.type);
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (obj == null || getClass() != obj.getClass()) return false;
|
||||||
|
Character other = (Character) obj;
|
||||||
|
return Objects.equals(name, other.name) && type == other.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name + " (" + type + ")";
|
return name + " (" + type + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
// seems legit to me
|
public String getName() {
|
||||||
return name.hashCode() * type.hashCode();
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package characters;
|
package characters;
|
||||||
|
|
||||||
import enums.CharacterType;
|
import enums.CharacterType;
|
||||||
import story.StoryContext;
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Child extends Character {
|
public class Child extends Character {
|
||||||
|
String thoughts = "";
|
||||||
|
|
||||||
public Child(String name) {
|
public Child(String name) {
|
||||||
super(CharacterType.CHILD, name);
|
super(CharacterType.CHILD, name);
|
||||||
|
@ -11,21 +13,37 @@ public class Child extends Character {
|
||||||
|
|
||||||
// Child can listen to stories about the city and ask questions about the subject of the story
|
// Child can listen to stories about the city and ask questions about the subject of the story
|
||||||
|
|
||||||
public String listenAbout(String context) {
|
public void think(String story) {
|
||||||
return name + " слушает историю о " + context;
|
if (story.contains("город")) {
|
||||||
|
this.thoughts += "Я никогда не был в городе, но история о " + context.getStoryContext() + " мне очень понравилась\n";
|
||||||
|
} else if (story.contains("путешествие")) {
|
||||||
|
this.thoughts += "Не люблю я путешествовать, но история о " + context.getStoryContext() + " мне очень понравилась\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.thoughts += "Интересная получается история о " + context.getStoryContext() + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String listenAbout(String context, String subject) {
|
public String converse(String subject) {
|
||||||
return name + " слушает историю о " + context + " и спрашивает вопросы о " + subject;
|
String response = this.name + " слушает историю о " + context.getStoryContext() + " и спрашивает вопросы о " + subject;
|
||||||
|
this.thoughts = "";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String converse(StoryContext context, String subject) {
|
public String listen(String subject) {
|
||||||
return listenAbout(context.getStoryContext(), subject);
|
String response = this.name + " слушает историю о " + context.getStoryContext() + " и спрашивает вопросы о " + subject;
|
||||||
|
this.thoughts = "";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void discussTravelers(List<Traveler> travelers){
|
||||||
public String listen(StoryContext context) {
|
System.out.println(this.name + " обсуждает путешественников: ");
|
||||||
return listenAbout(context.getStoryContext());
|
|
||||||
|
for(Traveler t: travelers){
|
||||||
|
if(t.isHome()){
|
||||||
|
System.out.println(t.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,23 +1,55 @@
|
||||||
package characters;
|
package characters;
|
||||||
|
|
||||||
|
import enums.AdventureType;
|
||||||
import enums.CharacterType;
|
import enums.CharacterType;
|
||||||
import story.StoryContext;
|
import story.Adventure;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class Traveler extends Character {
|
public abstract class Traveler extends Character {
|
||||||
|
private boolean isHome;
|
||||||
|
private final List<Adventure> adventures;
|
||||||
|
|
||||||
public Traveler(String name) {
|
public Traveler(String name) {
|
||||||
super(CharacterType.TRAVELER, name);
|
super(CharacterType.TRAVELER, name);
|
||||||
|
this.adventures = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traveler can tell stories about his adventures and listen to stories about the city, but dont ask questions
|
// Traveler can tell stories about his adventures and listen to stories about the city, but dont ask questions
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String listen(StoryContext context) {
|
public String converse(String subject) {
|
||||||
return name + " слушает историю о " + context.getStoryContext();
|
return this.name + " рассказывает историю о " + context.getStoryContext() + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAdventure(String adventureStory) {
|
||||||
|
Adventure newAdventure = new Adventure(adventureStory, AdventureType.FAMOUS, List.of(this));
|
||||||
|
this.adventures.add(newAdventure);
|
||||||
|
}
|
||||||
|
public void addAdventure(Adventure adventureStory) {
|
||||||
|
this.adventures.add(adventureStory);
|
||||||
|
}
|
||||||
|
public void addAdventure(String adventureStory, List<Traveler> travelers) {
|
||||||
|
travelers.add(this);
|
||||||
|
Adventure newAdventure = new Adventure(adventureStory, AdventureType.FAMOUS, travelers);
|
||||||
|
this.adventures.add(newAdventure);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Adventure> getAdventures() {
|
||||||
|
return this.adventures;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void returnHome() {
|
||||||
|
this.isHome = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHome() {
|
||||||
|
return isHome;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String converse(StoryContext context, String subject) {
|
public String listen(String subject) {
|
||||||
return name + " рассказывает историю о " + subject;
|
return this.name + " слушает историю о " + context.getStoryContext() + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,42 @@
|
||||||
package characters;
|
package characters;
|
||||||
|
|
||||||
import interfaces.Conversable;
|
import java.util.List;
|
||||||
import interfaces.Listenable;
|
|
||||||
import story.StoryContext;
|
|
||||||
|
|
||||||
public class Znayka extends Traveler implements Listenable, Conversable {
|
public class Znayka extends Traveler {
|
||||||
|
String thoughts = "";
|
||||||
|
|
||||||
public Znayka() {
|
public Znayka() {
|
||||||
super("Знайка");
|
super("Знайка");
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public String listen(StoryContext context) {
|
public String thinkAbout(String story) {
|
||||||
return name + " умно слушает историю о " + context.getStoryContext();
|
if (story.contains("город")) {
|
||||||
|
return "Немного я знаю о городах, но история о " + context.getStoryContext() + " мне очень понравилась\n";
|
||||||
|
} else if (story.contains("путешествие")) {
|
||||||
|
return "Я люблю путешествовать, история о " + context.getStoryContext() + " мне очень понравилась\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "Интересная получается история о " + context.getStoryContext() + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void think(String story) {
|
||||||
|
this.thoughts += thinkAbout(story);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String converse(StoryContext context, String subject) {
|
public String converse(String subject) {
|
||||||
return name + " умно рассказывает историю о " + subject;
|
String response = name + " умно рассказывает историю о " + subject
|
||||||
|
+ "\n" + "и думает: " + thinkAbout(subject);
|
||||||
|
this.thoughts = "";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String listen(String subject) {
|
||||||
|
String response = name + " умно слушает историю о " + context.getStoryContext() + " особенно про " + subject
|
||||||
|
+ "\n" + "и думает: " + this.thoughts;
|
||||||
|
this.thoughts = "";
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6
src/enums/AdventureType.java
Normal file
6
src/enums/AdventureType.java
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package enums;
|
||||||
|
|
||||||
|
public enum AdventureType {
|
||||||
|
FAMOUS, // Represents adventures that are famous
|
||||||
|
UNKNOWN // Represents adventures that are unknown
|
||||||
|
}
|
7
src/enums/LifeType.java
Normal file
7
src/enums/LifeType.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package enums;
|
||||||
|
|
||||||
|
public enum LifeType {
|
||||||
|
NOT_AS_USUAL, // Represents life not as usual
|
||||||
|
AS_USUAL, // Represents life as usual
|
||||||
|
|
||||||
|
}
|
13
src/exceptions/StoryEventException.java
Normal file
13
src/exceptions/StoryEventException.java
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package exceptions;
|
||||||
|
|
||||||
|
public class StoryEventException extends Exception {
|
||||||
|
public StoryEventException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStackTrace() {
|
||||||
|
System.out.println("Неожиданное исключение во время выполнения события: " + this.getMessage());
|
||||||
|
super.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
package exceptions;
|
|
||||||
|
|
||||||
public class StoryException extends Exception {
|
|
||||||
public StoryException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
13
src/exceptions/StoryLogicException.java
Normal file
13
src/exceptions/StoryLogicException.java
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package exceptions;
|
||||||
|
|
||||||
|
public class StoryLogicException extends RuntimeException {
|
||||||
|
public StoryLogicException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStackTrace() {
|
||||||
|
System.err.println("Ошибка логики истории: " + this.getMessage());
|
||||||
|
super.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
package exceptions;
|
|
||||||
|
|
||||||
public class StoryRuntimeException extends RuntimeException {
|
|
||||||
public StoryRuntimeException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,8 @@
|
||||||
package interfaces;
|
package interfaces;
|
||||||
|
|
||||||
import story.StoryContext;
|
|
||||||
|
|
||||||
public interface Conversable {
|
public interface Conversable {
|
||||||
String converse(StoryContext context, String subject);
|
String converse(String subject);
|
||||||
|
|
||||||
|
void think(String story);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package interfaces;
|
package interfaces;
|
||||||
|
|
||||||
import story.StoryContext;
|
|
||||||
|
|
||||||
public interface Listenable {
|
public interface Listenable {
|
||||||
String listen(StoryContext context);
|
String listen(String subject);
|
||||||
}
|
}
|
|
@ -1,19 +1,72 @@
|
||||||
package model;
|
package model;
|
||||||
|
|
||||||
public class City extends StoryElement {
|
import characters.Child;
|
||||||
private final String name;
|
import characters.Traveler;
|
||||||
|
import enums.LifeType;
|
||||||
|
import exceptions.StoryEventException;
|
||||||
|
import story.Adventure;
|
||||||
|
import story.StoryEvent;
|
||||||
|
|
||||||
public City(String name) {
|
import java.util.ArrayList;
|
||||||
super(name); // Assuming the super class StoryElement's constructor takes a name or description
|
import java.util.List;
|
||||||
|
|
||||||
|
public class City extends Location {
|
||||||
|
private final String name;
|
||||||
|
private final LifeType lifeType;
|
||||||
|
private final List<Traveler> travelers;
|
||||||
|
private final List<Child> children;
|
||||||
|
private final List<House> houses;
|
||||||
|
|
||||||
|
|
||||||
|
public City(String name, LifeType lifeType) {
|
||||||
|
super(name);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.lifeType = lifeType;
|
||||||
|
travelers = new ArrayList<>();
|
||||||
|
children = new ArrayList<>();
|
||||||
|
houses = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTraveler(Traveler traveler) {
|
||||||
|
travelers.add(traveler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChild(Child child) {
|
||||||
|
children.add(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHouse(House house) {
|
||||||
|
houses.add(house);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void returnToDailyLifeWithChanges() {
|
public void returnToDailyLife() {
|
||||||
// Implementation of the method as before
|
if (this.lifeType == LifeType.NOT_AS_USUAL) {
|
||||||
System.out.println("Жизнь в " + this.getName() + " потекла по-старому... хотя нет, нельзя сказать, чтобы совсем по-старому.");
|
System.out.println("Жизнь в " + this.name + " потекла по-старому... хотя нет, нельзя сказать, чтобы совсем по-старому.");
|
||||||
|
} else {
|
||||||
|
System.out.println("Жизнь в " + this.name + " потекла по-старому.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void celebrateReturnOfTravelers() throws StoryEventException {
|
||||||
|
if (travelers.isEmpty()) {
|
||||||
|
throw new StoryEventException("Никто не пришел на вечеринку :(");
|
||||||
|
}
|
||||||
|
StoryEvent celebrationEvent = new StoryEvent("Возвращение путешественников") {
|
||||||
|
@Override
|
||||||
|
public void occur() {
|
||||||
|
System.out.println("Жители " + City.this.name + " собрались вместе, чтобы отпраздновать возвращение путешественников.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
celebrationEvent.occur();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recognizeTravelers() {
|
||||||
|
for (Traveler traveler : travelers) {
|
||||||
|
System.out.println("С тех пор как наши отважные путешественники " + traveler.getName() + " вернулись домой, в городе только и говорили о них.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,32 @@
|
||||||
package model;
|
package model;
|
||||||
|
|
||||||
import characters.Character;
|
import characters.Character;
|
||||||
import exceptions.StoryRuntimeException;
|
import characters.Traveler;
|
||||||
import interfaces.Interactable;
|
import exceptions.StoryLogicException;
|
||||||
|
import story.Adventure;
|
||||||
import story.StoryContext;
|
import story.StoryContext;
|
||||||
|
import characters.Child;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class House extends StoryElement {
|
public class House extends Location {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final List<Character> residents;
|
private final List<Character> residents;
|
||||||
|
private final Character owner;
|
||||||
|
private final City city;
|
||||||
|
public Character getOwner() {
|
||||||
|
return this.owner;
|
||||||
|
}
|
||||||
|
|
||||||
public House(String name) {
|
public House(String name, Character owner, City city) {
|
||||||
super(name);
|
super(name);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.residents = new ArrayList<>();
|
this.residents = new ArrayList<>();
|
||||||
|
this.owner = owner;
|
||||||
|
this.city = city;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkReadinessForStorytelling() {
|
|
||||||
if (this.residents.isEmpty()) {
|
|
||||||
throw new StoryRuntimeException("The house is empty, no one to tell stories to.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
@ -43,38 +45,58 @@ public class House extends StoryElement {
|
||||||
return residents;
|
return residents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tellEveningStories(StoryContext context, List<String> subjects) {
|
public List<Traveler> getTravelers() {
|
||||||
checkReadinessForStorytelling();
|
List<Traveler> travelers = new ArrayList<>();
|
||||||
logger.logInteraction("Starting evening stories session");
|
|
||||||
context.gatherResidentsForStories();
|
|
||||||
context.getCity().returnToDailyLifeWithChanges();
|
|
||||||
|
|
||||||
this.gatherResidents();
|
|
||||||
for (String subject: subjects) {
|
|
||||||
for (Character resident : this.getResidents()) {
|
for (Character resident : this.getResidents()) {
|
||||||
String event;
|
if (resident instanceof Traveler) {
|
||||||
// if (resident instanceof Traveler) {
|
travelers.add((Traveler) resident);
|
||||||
// event = resident.converse(context, subject);
|
|
||||||
// } else {
|
|
||||||
// event = resident.listen(context);
|
|
||||||
// }
|
|
||||||
// now can just converse for everyone
|
|
||||||
event = resident.converse(context, subject);
|
|
||||||
System.out.println(event);
|
|
||||||
|
|
||||||
if (Math.random() > 0.80) {
|
|
||||||
new Interactable() {
|
|
||||||
@Override
|
|
||||||
public void interact(StoryContext context) {
|
|
||||||
System.out.println("Внезапный флешбенгер");
|
|
||||||
logger.logInteraction("Внезапный флешбенгер");
|
|
||||||
}
|
|
||||||
}.interact(context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return travelers;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The method could end with a closing statement or a setup for the next day's stories.
|
public void tellEveningStories(Adventure adventure) {
|
||||||
System.out.println("Истории захватывали дух, и каждый вечер собирались всё больше жителей, чтобы слышать новые приключения.");
|
List<Traveler> travelingResidents = this.getTravelers();
|
||||||
|
|
||||||
|
if (!travelingResidents.isEmpty()) {
|
||||||
|
this.gatherResidents();
|
||||||
|
|
||||||
|
StoryContext context = adventure.getContext(city, this);
|
||||||
|
System.out.println("Все жители слушают историю о путешествии в " + adventure.getAdventureName() + " в " + adventure.getAdventurePlace());
|
||||||
|
narrateSpecialStory(adventure);
|
||||||
|
for (Character resident : this.getResidents()) {
|
||||||
|
resident.setContext(context);
|
||||||
|
if (resident instanceof Traveler) {
|
||||||
|
String response = resident.converse(context.getStoryContext());
|
||||||
|
System.out.println(resident.getName() + " рассказывает: " + response);
|
||||||
|
}
|
||||||
|
else if (resident instanceof Child) {
|
||||||
|
String response = resident.listen(context.getStoryContext());
|
||||||
|
System.out.println(resident.getName() + " слушает: " + response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Истории захватывали дух, и каждый вечер собирались всё больше жителей, чтобы слушать новые приключения.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void gatherChildren(List<Child> children) {
|
||||||
|
List<String> childrenNames = new ArrayList<>();
|
||||||
|
for (Child child : children) {
|
||||||
|
childrenNames.add(child.getName());
|
||||||
|
}
|
||||||
|
System.out.println(String.join(",", childrenNames) + " собираются в доме " + owner.getName() + " чтобы послушать истории");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void narrateSpecialStory(Adventure adventure) throws StoryLogicException {
|
||||||
|
if (residents.isEmpty()) {
|
||||||
|
throw new StoryLogicException("Никто не может рассказать историю, если никто не живет в доме");
|
||||||
|
}
|
||||||
|
class SpecialStory {
|
||||||
|
void narrate() {
|
||||||
|
System.out.println("И вот, когда все собрались в доме " + owner.getName() + ", " + owner.getName() + " рассказал историю о том, как он " + adventure.getAdventureName() + " в " + adventure.getAdventurePlace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SpecialStory specialStory = new SpecialStory();
|
||||||
|
specialStory.narrate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/model/Location.java
Normal file
16
src/model/Location.java
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package model;
|
||||||
|
|
||||||
|
import story.StoryElement;
|
||||||
|
|
||||||
|
abstract public class Location extends StoryElement {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public Location(String name) {
|
||||||
|
super(name);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
70
src/story/Adventure.java
Normal file
70
src/story/Adventure.java
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package story;
|
||||||
|
|
||||||
|
import characters.Traveler;
|
||||||
|
import enums.AdventureType;
|
||||||
|
import exceptions.StoryEventException;
|
||||||
|
import model.City;
|
||||||
|
import model.House;
|
||||||
|
import model.Location;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Adventure {
|
||||||
|
public String name;
|
||||||
|
private Location location;
|
||||||
|
private final AdventureType type;
|
||||||
|
private List<Traveler> travelers = new ArrayList<>();
|
||||||
|
|
||||||
|
public Adventure(String name, AdventureType type, List<Traveler> travelers) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.travelers = travelers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(Location location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getLocation() {
|
||||||
|
return this.location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end() throws StoryEventException{
|
||||||
|
if (travelers.isEmpty()) {
|
||||||
|
throw new StoryEventException("Некому закончить приключение");
|
||||||
|
}
|
||||||
|
List<String> travelersNames = new ArrayList<>();
|
||||||
|
for (Traveler traveler : this.travelers) {
|
||||||
|
travelersNames.add(traveler.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type == AdventureType.FAMOUS) {
|
||||||
|
System.out.println("На этом знаменитое путешествие " + String.join(", ", travelersNames) + " закончилось.");
|
||||||
|
} else {
|
||||||
|
System.out.println("На этом путешествие " + String.join(", ", travelersNames) + " закончилось.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAdventurePlace() {
|
||||||
|
return this.location.getName();
|
||||||
|
}
|
||||||
|
public String getAdventureName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
public StoryContext getContext(City city, House house){
|
||||||
|
return new StoryContext(city, house, this.getAdventureName());
|
||||||
|
}
|
||||||
|
public static class Challenge {
|
||||||
|
public void present() {
|
||||||
|
System.out.println("Путешественники столкнулись с проблемой");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-Static Nested Class for Memory
|
||||||
|
public class Memory {
|
||||||
|
public void recall() {
|
||||||
|
System.out.println("Путешественники вспомнили о " + Adventure.this.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ package story;
|
||||||
import model.City;
|
import model.City;
|
||||||
import model.House;
|
import model.House;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class StoryContext {
|
public class StoryContext {
|
||||||
private final City city;
|
private final City city;
|
||||||
private final House house;
|
private final House house;
|
||||||
|
|
35
src/story/StoryElement.java
Normal file
35
src/story/StoryElement.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package story;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public abstract class StoryElement {
|
||||||
|
protected String description;
|
||||||
|
|
||||||
|
public StoryElement(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName() + "{" +
|
||||||
|
"description='" + description + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (obj == null || getClass() != obj.getClass()) return false;
|
||||||
|
StoryElement that = (StoryElement) obj;
|
||||||
|
return Objects.equals(description, that.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return description != null ? description.hashCode() : 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package story;
|
package story;
|
||||||
|
|
||||||
class StoryEvent {
|
public class StoryEvent {
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
public StoryEvent(String description) {
|
public StoryEvent(String description) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user