From da7c6aa397ab3d503b9328211e5aaa932c071524 Mon Sep 17 00:00:00 2001 From: LeterZP Date: Fri, 13 Feb 2026 00:17:04 +0300 Subject: [PATCH] ProgLab3 --- environment/BadVisibilityException.java | 8 + environment/EmptyCropException.java | 8 + environment/Environment.java | 33 +++ environment/FatigueException.java | 8 + environment/Ground.java | 18 ++ environment/MainCharacter.java | 254 ++++++++++++++++++++++++ environment/Weather.java | 3 + food/Apple.java | 12 ++ food/Banana.java | 12 ++ food/Beetroot.java | 17 ++ food/Carrot.java | 19 ++ food/Color.java | 3 + food/Eatable.java | 9 + food/Fruit.java | 67 +++++++ food/Garlic.java | 17 ++ food/Pear.java | 12 ++ food/Plant.java | 60 ++++++ food/Potato.java | 19 ++ food/Radish.java | 17 ++ food/State.java | 3 + food/Tree.java | 58 ++++++ food/Vegetable.java | 86 ++++++++ main/Main.java | 17 ++ 23 files changed, 760 insertions(+) create mode 100644 environment/BadVisibilityException.java create mode 100644 environment/EmptyCropException.java create mode 100644 environment/Environment.java create mode 100644 environment/FatigueException.java create mode 100644 environment/Ground.java create mode 100644 environment/MainCharacter.java create mode 100644 environment/Weather.java create mode 100644 food/Apple.java create mode 100644 food/Banana.java create mode 100644 food/Beetroot.java create mode 100644 food/Carrot.java create mode 100644 food/Color.java create mode 100644 food/Eatable.java create mode 100644 food/Fruit.java create mode 100644 food/Garlic.java create mode 100644 food/Pear.java create mode 100644 food/Plant.java create mode 100644 food/Potato.java create mode 100644 food/Radish.java create mode 100644 food/State.java create mode 100644 food/Tree.java create mode 100644 food/Vegetable.java create mode 100644 main/Main.java diff --git a/environment/BadVisibilityException.java b/environment/BadVisibilityException.java new file mode 100644 index 0000000..a14b93d --- /dev/null +++ b/environment/BadVisibilityException.java @@ -0,0 +1,8 @@ +package environment; + +public class BadVisibilityException extends Exception { + @Override + public String getMessage() { + return "Плохая видимость, дальнейшее изучение локации невозможно."; + } +} diff --git a/environment/EmptyCropException.java b/environment/EmptyCropException.java new file mode 100644 index 0000000..76b9b8f --- /dev/null +++ b/environment/EmptyCropException.java @@ -0,0 +1,8 @@ +package environment; + +public class EmptyCropException extends Exception { + @Override + public String getMessage() { + return "На посеве больше не осталость продуктов."; + } +} diff --git a/environment/Environment.java b/environment/Environment.java new file mode 100644 index 0000000..5ed5490 --- /dev/null +++ b/environment/Environment.java @@ -0,0 +1,33 @@ +package environment; + +import food.*; +import java.util.ArrayList; + +public record Environment(ArrayList trees, + ArrayList plants, + Weather weather, + Ground ground) { + public Environment { + if (ground != Ground.ASPHALT && ground != Ground.SAND) { + if (weather != Weather.WIND) { + int rand = (int) (Math.random() * 8); + for (int i = 0; i < rand; i++) { + trees.add(new Tree()); + } + } + if (weather != Weather.SNOW) { + int rand = (int) (Math.random() * 8); + for (int i = 0; i < rand; i++) { + plants.add(new Plant()); + } + } + } + } + + public Environment() { + this(new ArrayList<>(), + new ArrayList<>(), + Weather.values()[(int) (Math.random() * Weather.values().length)], + Ground.values()[(int) (Math.random() * Ground.values().length)]); + } +} diff --git a/environment/FatigueException.java b/environment/FatigueException.java new file mode 100644 index 0000000..6906835 --- /dev/null +++ b/environment/FatigueException.java @@ -0,0 +1,8 @@ +package environment; + +public class FatigueException extends RuntimeException { + @Override + public String getMessage() { + return "Энергия закончилась."; + } +} diff --git a/environment/Ground.java b/environment/Ground.java new file mode 100644 index 0000000..e4a0e32 --- /dev/null +++ b/environment/Ground.java @@ -0,0 +1,18 @@ +package environment; + +enum Ground { + DIRT(0.3), + GRASS(0.5), + ASPHALT(0.8), + SAND(0.2); + + private final double comfort; + + Ground(double comfort) { + this.comfort = comfort; + } + + public double getComfort() { + return comfort; + } +} diff --git a/environment/MainCharacter.java b/environment/MainCharacter.java new file mode 100644 index 0000000..244b831 --- /dev/null +++ b/environment/MainCharacter.java @@ -0,0 +1,254 @@ +package environment; + +import java.util.ArrayList; +import food.*; + +public class MainCharacter { + private final String name; + private double mood; + private double energy; + private ArrayList inventory; + private Environment location; + + public MainCharacter(String name) { + this.name = name; + this.mood = Math.random(); + this.energy = Math.random(); + this.inventory = new ArrayList<>(); + } + + public String toString() { + return this.getName(); + } + + public boolean equals(Object object) { + if (this == object) return true; + if (object == null) return false; + if (this.getClass() == object.getClass()) { + MainCharacter character = (MainCharacter) object; + return this.getName().equals(character.getName()); + } return false; + } + + public int hashCode() { + return this.getName().hashCode(); + } + + public String getName() { + return this.name; + } + + public double getMood() { + return this.mood; + } + + public double getEnergy() { + return this.energy; + } + + public ArrayList getInventory() { + return this.inventory; + } + + public Environment getLocation() { + return this.location; + } + + public void setMood(double mood) { + this.mood = mood; + if (this.getMood() > 1) this.mood = 1; + if (this.getMood() < 0) this.mood = 0; + } + + public void setEnergy(double energy) throws FatigueException { + this.energy = energy; + if (this.getEnergy() > 1) this.energy = 1; + if (this.getEnergy() < 0) { + System.out.println(this + " устал."); + throw new FatigueException(); + } + } + + public void changeMood(double change) { + this.setMood(this.getMood() + change); + } + + public void changeEnergy(double change) { + this.setEnergy(this.getEnergy() + change); + } + + public void addToInventory(Eatable eatable) { + this.getInventory().add(eatable); + } + + public void finalWords() { + if (this.getMood() < 0.25) { + System.out.println(this + " проклинает всех, кто выращивал эти посевы."); + } else if (this.getMood() < 0.5) { + System.out.println(this + " слегка недоволен своим небольшим путешествием."); + } else if (this.getMood() < 0.75) { + System.out.println(this + " остался доволен и сыт."); + } else { + System.out.println(this + " боготворит тех, кто посадил такие вкусные посевы."); + } + } + + public void goToLocation(Environment env) { + System.out.println(this + " перемещается в новую локацию."); + this.location = env; + try { + this.lookAround(env); + } catch (BadVisibilityException e) { + this.goToLocation(new Environment()); + } + + } + + public void lookAround(Environment env) throws BadVisibilityException { + System.out.println(this + " осматривается."); + this.changeEnergy(-0.1); + System.out.println(this + " видит " + env.weather() + " и " + env.ground() + "."); + switch (env.weather()) { + case SUN: + this.changeMood(0.08); + System.out.println(this + " радуется " + env.weather() + "."); + break; + case FOG: + System.out.println(env.weather() + " блокирует видимость, поэтому " + this + " идет дальше."); + throw new BadVisibilityException(); + } + this.changeMood(env.ground().getComfort() - 0.5); + if (env.ground().getComfort() < 0.5) { + System.out.println(this + " не нравится идти по " + env.ground() + "."); + } else { + System.out.println(this + " нравится идти по " + env.ground() + "."); + } + try { + if (Math.random() < 0.5 && !env.trees().isEmpty()) { + Tree tree = env.trees().get((int) (Math.random() * env.trees().size())); + System.out.println(this + " замечает " + tree + "."); + this.snatchCrop(tree); + } else if (!env.plants().isEmpty()) { + Plant plant = env.plants().get((int) (Math.random() * env.plants().size())); + System.out.println(this + " замечает " + plant + "."); + this.snatchCrop(plant); + } else { + System.out.println(this + " не замечает никаких посевов."); + } + } catch (EmptyCropException e) { + System.out.println(this + " не находит посевов, поэтому теряет интерес."); + } + } + + public void snatchCrop(Plant plant) throws EmptyCropException { + this.changeEnergy(-0.03); + if (plant.getVegetablesAmount() == 0) throw new EmptyCropException(); + int rand = (int) (Math.random()*plant.getVegetablesAmount()); + System.out.println(this + " срывает " + plant.getVegetables().get(rand) + "."); + addToInventory(plant.getVegetables().get(rand)); + plant.getVegetables().remove(rand); + if (Math.random() < 0.8) { + this.analyseCrop(this.getInventory().get(this.getInventory().size()-1)); + } + if (Math.random() < 0.4 && plant.getVegetablesAmount() != 0) { + System.out.println(this + " решает собрать больше посевов."); + rand = (int) (Math.random() * plant.getVegetablesAmount()); + snatchCrop(plant, rand); + } + } + + public void snatchCrop(Tree tree) throws EmptyCropException { + this.changeEnergy(-0.03); + if (tree.getFruitsAmount() == 0) throw new EmptyCropException(); + int rand = (int) (Math.random()*tree.getFruitsAmount()); + System.out.println(this + " срывает " + tree.getFruits().get(rand) + "."); + addToInventory(tree.getFruits().get(rand)); + tree.getFruits().remove(rand); + if (Math.random() < 0.8) { + this.analyseCrop(this.getInventory().get(this.getInventory().size()-1)); + } + if (Math.random() < 0.4 && tree.getFruitsAmount() != 0) { + System.out.println(this + " решает собрать больше посевов."); + rand = (int) (Math.random() * tree.getFruitsAmount() + 1); + snatchCrop(tree, rand); + } + } + + public void snatchCrop(Plant plant, int count) { + for (int i = 0; i < count; i++) { + addToInventory(plant.getVegetables().get(plant.getVegetablesAmount()-1)); + plant.getVegetables().remove(plant.getVegetablesAmount()-1); + } + System.out.println(this + " собрал " + count + " " + this.getInventory().get(this.getInventory().size()-1) + "."); + } + + public void snatchCrop(Tree tree, int count) { + for (int i = 0; i < count; i++) { + addToInventory(tree.getFruits().get(tree.getFruitsAmount()-1)); + tree.getFruits().remove(tree.getFruitsAmount()-1); + } + System.out.println(this + " собрал " + count + " " + this.getInventory().get(this.getInventory().size()-1) + "."); + } + + public void analyseCrop(Eatable eatable) { + if (Math.random() < 0.5) { + this.guessFoodType(); + } + if (Math.random() < 0.7) { + this.guessCrop(); + } + if (Math.random() < 0.9) { + tasteCrop(eatable); + } + } + + public void guessFoodType() { + this.changeEnergy(-0.01); + if (Math.random() < 0.5) { + this.changeMood(0.05); + System.out.println(this + " угадывает место произростания посева."); + } else { + this.changeMood(-0.05); + System.out.println(this + " не угадывает место произростания посева."); + } + } + + public void guessCrop() { + this.changeEnergy(-0.01); + if (Math.random() < 0.5) { + this.changeMood(0.08); + System.out.println(this + " угадывает вид посева."); + } else { + this.changeMood(-0.08); + System.out.println(this + " не угадывает вид посева."); + } + } + + public void tasteCrop(Eatable eatable) { + if (eatable instanceof Vegetable) { + Vegetable vegetable = (Vegetable) eatable; + if (Math.random() < 0.1) { + vegetable.setCookedState(State.values()[(int) (Math.random() * 3 + 1)]); + System.out.println(this + " готовит " + vegetable + "," + + " получая " + vegetable.getCookedState() + " " + vegetable + "."); + } + if (Math.random() < 0.1) { + vegetable.peel(); + System.out.println(this + " чистит " + vegetable + "."); + } + } + System.out.println(this + " пробует " + eatable + "."); + if (Math.random() < eatable.getTaste()) { + this.changeMood(0.3); + System.out.println(this + " доволен."); + } else { + this.changeMood(-0.3); + System.out.println(this + " недоволен."); + } + } + + public void stumble() { + this.changeMood(-0.1); + System.out.println(this + " споткнулся."); + } +} diff --git a/environment/Weather.java b/environment/Weather.java new file mode 100644 index 0000000..02a15e1 --- /dev/null +++ b/environment/Weather.java @@ -0,0 +1,3 @@ +package environment; + +public enum Weather {SUN, FOG, RAIN, SNOW, WIND} diff --git a/food/Apple.java b/food/Apple.java new file mode 100644 index 0000000..675804a --- /dev/null +++ b/food/Apple.java @@ -0,0 +1,12 @@ +package food; + +public class Apple extends Fruit { + public Apple() { + super(); + } + + @Override + public String toString() { + return "яблоко"; + } +} diff --git a/food/Banana.java b/food/Banana.java new file mode 100644 index 0000000..0baf05e --- /dev/null +++ b/food/Banana.java @@ -0,0 +1,12 @@ +package food; + +public class Banana extends Fruit { + public Banana() { + super(); + } + + @Override + public String toString() { + return "банан"; + } +} diff --git a/food/Beetroot.java b/food/Beetroot.java new file mode 100644 index 0000000..69c7588 --- /dev/null +++ b/food/Beetroot.java @@ -0,0 +1,17 @@ +package food; + +public class Beetroot extends Vegetable{ + public Beetroot() { + super(); + } + + @Override + public String toString() { + return "свёкла"; + } + + @Override + public void peel() { + this.changeTaste(Math.random()*0.1); + } +} diff --git a/food/Carrot.java b/food/Carrot.java new file mode 100644 index 0000000..8fabf2e --- /dev/null +++ b/food/Carrot.java @@ -0,0 +1,19 @@ +package food; + +import java.util.ArrayList; + +public class Carrot extends Vegetable{ + public Carrot() { + super(); + } + + @Override + public String toString() { + return "морковь"; + } + + @Override + public void peel() { + this.changeTaste(Math.random()*0.2); + } +} diff --git a/food/Color.java b/food/Color.java new file mode 100644 index 0000000..410871f --- /dev/null +++ b/food/Color.java @@ -0,0 +1,3 @@ +package food; + +public enum Color {WHITE, YELLOW, PURPLE, ORANGE, CRIMSON, BLACK, PINK, RED, GREEN} \ No newline at end of file diff --git a/food/Eatable.java b/food/Eatable.java new file mode 100644 index 0000000..fb03096 --- /dev/null +++ b/food/Eatable.java @@ -0,0 +1,9 @@ +package food; + +public interface Eatable { + double getTaste(); + Color getColor(); + void setTaste(double taste); + void setColor(Color color); + void changeTaste(double change); +} diff --git a/food/Fruit.java b/food/Fruit.java new file mode 100644 index 0000000..0188126 --- /dev/null +++ b/food/Fruit.java @@ -0,0 +1,67 @@ +package food; + +public abstract class Fruit implements Eatable{ + private double taste; + private Color color; + + public Fruit() { + this.taste = Math.random(); + this.color = Color.values()[(int) (Math.random() * Color.values().length)]; + } + + @Override + public String toString() { + return "фрукт"; + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (object == null) return false; + if (this.getClass() == object.getClass()) { + Fruit fruit = (Fruit) object; + return this.getTaste() == fruit.getTaste() + && this.getColor() == fruit.getColor(); + } return false; + } + + @Override + public int hashCode() { + int total = 0; + total += (int) (this.getTaste() * Math.pow(10, 8)); + for (int i = 0; i < Color.values().length; i++) { + if (Color.values()[i] == this.getColor()) { + total += (int) (i * Math.pow(10, 8)); + break; + } + } + return total; + } + + @Override + public double getTaste() { + return this.taste; + } + + @Override + public Color getColor() { + return this.color; + } + + @Override + public void setTaste(double taste) { + this.taste = taste; + if (this.taste > 1) this.taste = 1; + else if (this.taste < 0) this.taste = 0; + } + + @Override + public void setColor(Color color) { + this.color = color; + } + + @Override + public void changeTaste(double change) { + setTaste(this.taste + change); + } +} diff --git a/food/Garlic.java b/food/Garlic.java new file mode 100644 index 0000000..33bca2f --- /dev/null +++ b/food/Garlic.java @@ -0,0 +1,17 @@ +package food; + +public class Garlic extends Vegetable{ + public Garlic() { + super(); + } + + @Override + public String toString() { + return "чеснок"; + } + + @Override + public void peel() { + this.changeTaste(Math.random()*0.2); + } +} \ No newline at end of file diff --git a/food/Pear.java b/food/Pear.java new file mode 100644 index 0000000..563e2d2 --- /dev/null +++ b/food/Pear.java @@ -0,0 +1,12 @@ +package food; + +public class Pear extends Fruit { + public Pear() { + super(); + } + + @Override + public String toString() { + return "груша"; + } +} diff --git a/food/Plant.java b/food/Plant.java new file mode 100644 index 0000000..12d9b09 --- /dev/null +++ b/food/Plant.java @@ -0,0 +1,60 @@ +package food; + +import java.util.ArrayList; + +public class Plant { + private ArrayList vegetables = new ArrayList<>(); + + public Plant() { + int rand = (int) (Math.random() * 5) + 1; + for (int i = 0; i < (int) (Math.random() * 11) + 1; i++) { + switch (rand) { + case 1: addVegetable(new Potato()); break; + case 2: addVegetable(new Carrot()); break; + case 3: addVegetable(new Beetroot()); break; + case 4: addVegetable(new Garlic()); break; + case 5: addVegetable(new Radish()); break; + } + } + } + + @Override + public String toString() { + return "растение с " + this.getVegetables().get(0).toString(); + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (object == null) return false; + if (this.getClass() == object.getClass()) { + Plant plant = (Plant) object; + if (this.getVegetablesAmount() != plant.getVegetablesAmount()) return false; + for (int i = 0; i < this.getVegetablesAmount(); i++) { + if (this.getVegetables().get(i) != plant.getVegetables().get(i)) return false; + } + return true; + } return false; + } + + @Override + public int hashCode() { + int total = 0; + for (int i = 0; i < this.getVegetablesAmount(); i++) { + total = 31 * total + this.getVegetables().get(i).hashCode(); + } + return total; + } + + public ArrayList getVegetables() { + return vegetables; + } + + public int getVegetablesAmount() { + return vegetables.size(); + } + + public void addVegetable(Vegetable vegetable) { + vegetables.add(vegetable); + } +} diff --git a/food/Potato.java b/food/Potato.java new file mode 100644 index 0000000..88ee042 --- /dev/null +++ b/food/Potato.java @@ -0,0 +1,19 @@ +package food; + +import java.util.ArrayList; + +public class Potato extends Vegetable{ + public Potato() { + super(); + } + + @Override + public String toString() { + return "картофель"; + } + + @Override + public void peel() { + this.changeTaste(Math.random()*0.1); + } +} diff --git a/food/Radish.java b/food/Radish.java new file mode 100644 index 0000000..7c79ed8 --- /dev/null +++ b/food/Radish.java @@ -0,0 +1,17 @@ +package food; + +public class Radish extends Vegetable{ + public Radish() { + super(); + } + + @Override + public String toString() { + return "редис"; + } + + @Override + public void peel() { + this.changeTaste(Math.random()*0.1); + } +} diff --git a/food/State.java b/food/State.java new file mode 100644 index 0000000..d4fcfa3 --- /dev/null +++ b/food/State.java @@ -0,0 +1,3 @@ +package food; + +public enum State {RAW, FRIED, BOILED, ROTTEN} diff --git a/food/Tree.java b/food/Tree.java new file mode 100644 index 0000000..15cf16f --- /dev/null +++ b/food/Tree.java @@ -0,0 +1,58 @@ +package food; + +import java.util.ArrayList; + +public class Tree { + private ArrayList fruits = new ArrayList<>(); + + public Tree() { + int rand = (int) (Math.random()*3) + 1; + for (int i = 0; i < (int) (Math.random() * 11) + 1; i++) { + switch (rand) { + case 1: addFruit(new Apple()); break; + case 2: addFruit(new Banana()); break; + case 3: addFruit(new Pear()); break; + } + } + } + + @Override + public String toString() { + return "дерево с " + this.getFruits().get(0).toString(); + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (object == null) return false; + if (this.getClass() == object.getClass()) { + Tree tree = (Tree) object; + if (this.getFruitsAmount() != tree.getFruitsAmount()) return false; + for (int i = 0; i < this.getFruitsAmount(); i++) { + if (this.getFruits().get(i) != tree.getFruits().get(i)) return false; + } + return true; + } return false; + } + + @Override + public int hashCode() { + int total = 0; + for (int i = 0; i < this.getFruitsAmount(); i++) { + total = 31 * total + this.getFruits().get(i).hashCode(); + } + return total; + } + + public ArrayList getFruits() { + return fruits; + } + + public int getFruitsAmount() { + return fruits.size(); + } + + public void addFruit(Fruit fruit) { + fruits.add(fruit); + } +} \ No newline at end of file diff --git a/food/Vegetable.java b/food/Vegetable.java new file mode 100644 index 0000000..73a507b --- /dev/null +++ b/food/Vegetable.java @@ -0,0 +1,86 @@ +package food; + +public abstract class Vegetable implements Eatable{ + private double taste; + private Color color; + private State cookedState; + + public Vegetable() { + this.taste = Math.random() * 0.5; + this.color = Color.values()[(int) (Math.random() * Color.values().length)]; + this.cookedState = State.RAW; + } + + @Override + public String toString() { + return "овощ"; + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (object == null) return false; + if (this.getClass() == object.getClass()) { + Vegetable vegetable = (Vegetable) object; + return this.getTaste() == vegetable.getTaste() + && this.getColor() == vegetable.getColor() + && this.getCookedState() == vegetable.getCookedState(); + } return false; + } + + @Override + public int hashCode() { + int total = 0; + total += (int) (this.getTaste() * Math.pow(10, 7)); + for (int i = 0; i < Color.values().length; i++) { + if (Color.values()[i] == this.getColor()) { + total += (int) (i * Math.pow(10, 7)); + break; + } + } + for (int i = 0; i < State.values().length; i++) { + if (State.values()[i] == this.getCookedState()) { + total += (int) (i * Math.pow(10, 8)); + break; + } + } + return total; + } + + @Override + public double getTaste() { + return this.taste; + } + + @Override + public Color getColor() { + return this.color; + } + + @Override + public void setTaste(double taste) { + this.taste = taste; + if (this.taste > 1) this.taste = 1; + else if (this.taste < 0) this.taste = 0; + } + + @Override + public void setColor(Color color) { + this.color = color; + } + + @Override + public void changeTaste(double change) { + this.setTaste(this.taste + change); + } + + public State getCookedState() { + return this.cookedState; + } + + public void setCookedState(State cookedState) { + this.cookedState = cookedState; + } + + public abstract void peel(); +} diff --git a/main/Main.java b/main/Main.java new file mode 100644 index 0000000..9383501 --- /dev/null +++ b/main/Main.java @@ -0,0 +1,17 @@ +package main; + +import food.*; +import environment.*; + +public class Main { + public static void main(String[] args) { + MainCharacter character = new MainCharacter("Скуперфильд"); + try { + while (true) { + character.goToLocation(new Environment()); + } + } catch (FatigueException e) { + character.finalWords(); + } + } +} \ No newline at end of file