Epic Cosmos 1: обектите в космоса
Проблем
Космическа надпревара
Човечеството вече може да лети до далечни планети. Корпорации и държави се надпреварват за ресурсите им. Ти управляваш една от мисиите и искаш да станеш най-силната сила в космоса.
Правилата на Epic Cosmos:
- Точки се трупат с откриване на нови планети и обекти, добив на ресурси, строеж на сгради и кораби, научни открития.
- Обектите са звезди, планети и спътници. Звездата дава енергия. Някои планети имат редки ресурси, а атмосферата им решава какво може да се строи. Спътникът е за връзка и разузнаване.
- Ресурсите са нужни за строеж, проучвания и поддръжка на базите и корабите.
- Сградите добиват ресурси, проучват технологии, пазят базата и правят кораби.
- Технологиите отключват нови сгради, кораби и умения.
- Конфликти: в космоса не си сам. Има пирати и други играчи.
- Край: играта свършва, когато някой стигне определен брой точки или след определен брой ходове. Печели този с най-много точки.
Преди сградите и корабите ти трябва самият свят: какви обекти има, къде са и кой около кого може да обикаля. Това е урокът. Ресурсите, сградите и корабите са в следващия.
Идеята
Всичко в космоса е SpaceObject
Звездата, планетата и спътникът имат общо: име, координати x, y, z и маса. Общото отива в абстрактен клас:
abstract class SpaceObject { private String name; private double coordinateX; private double coordinateY; private double coordinateZ; private double mass;
public SpaceObject(String name, double coordinateX, double coordinateY, double coordinateZ, double mass) { this.name = name; this.coordinateX = coordinateX; this.coordinateY = coordinateY; this.coordinateZ = coordinateZ; this.mass = mass; }
public String getName() { return name; }
public double getCoordinateX() { return coordinateX; }
public double getCoordinateY() { return coordinateY; }
public double getCoordinateZ() { return coordinateZ; }
public double getMass() { return mass; }
public abstract String getKind();
public void displayInfo() { System.out.printf("%s %s: (%.1f, %.1f, %.1f), маса %.2f%n", getKind(), name, coordinateX, coordinateY, coordinateZ, mass); }
protected void moveTo(double x, double y, double z) { coordinateX = x; coordinateY = y; coordinateZ = z; }}abstract class SpaceObject{ public string Name { get; } public double CoordinateX { get; private set; } public double CoordinateY { get; private set; } public double CoordinateZ { get; private set; } public double Mass { get; }
public SpaceObject(string name, double coordinateX, double coordinateY, double coordinateZ, double mass) { Name = name; CoordinateX = coordinateX; CoordinateY = coordinateY; CoordinateZ = coordinateZ; Mass = mass; }
public abstract string GetKind();
public void DisplayInfo() { Console.WriteLine($"{GetKind()} {Name}: ({CoordinateX:F1}, {CoordinateY:F1}, {CoordinateZ:F1}), маса {Mass:F2}"); }
protected void MoveTo(double x, double y, double z) { CoordinateX = x; CoordinateY = y; CoordinateZ = z; }}class SpaceObject(ABC): def __init__(self, name, coordinate_x, coordinate_y, coordinate_z, mass): self._name = name self._coordinate_x = coordinate_x self._coordinate_y = coordinate_y self._coordinate_z = coordinate_z self._mass = mass
@property def name(self): return self._name
@property def coordinate_x(self): return self._coordinate_x
@property def coordinate_y(self): return self._coordinate_y
@property def coordinate_z(self): return self._coordinate_z
@property def mass(self): return self._mass
@abstractmethod def get_kind(self): pass
def display_info(self): print(f"{self.get_kind()} {self._name}: ({self._coordinate_x:.1f}, {self._coordinate_y:.1f}, {self._coordinate_z:.1f}), маса {self._mass:.2f}")
def _move_to(self, x, y, z): self._coordinate_x = x self._coordinate_y = y self._coordinate_z = zclass SpaceObject { #name; #coordinateX; #coordinateY; #coordinateZ; #mass;
constructor(name, coordinateX, coordinateY, coordinateZ, mass) { this.#name = name; this.#coordinateX = coordinateX; this.#coordinateY = coordinateY; this.#coordinateZ = coordinateZ; this.#mass = mass; }
get name() { return this.#name; }
get coordinateX() { return this.#coordinateX; }
get coordinateY() { return this.#coordinateY; }
get coordinateZ() { return this.#coordinateZ; }
get mass() { return this.#mass; }
getKind() { throw new Error(`${this.constructor.name} трябва да напише getKind()`); }
displayInfo() { console.log(`${this.getKind()} ${this.#name}: (${this.#coordinateX.toFixed(1)}, ${this.#coordinateY.toFixed(1)}, ${this.#coordinateZ.toFixed(1)}), маса ${this.#mass.toFixed(2)}`); }
_moveTo(x, y, z) { this.#coordinateX = x; this.#coordinateY = y; this.#coordinateZ = z; }}- Координатите са в милиони километри от Слънцето, а масата е в земни маси: Земята е 1, Слънцето е 333 000.
display_info()е общ за всички. Видът (get_kind()) е абстрактен: всеки наследник казва сам какъв е.-
_move_toзапочва с долна черта: това е уговорката за „само за класа и наследниците му“. Python не забранява викането отвън, но долната черта казва „не пипай“. Същото важи за полетатаself._nameи останалите, а отвън се четат през@property.
Абстрактният клас наследява ABC, а абстрактният метод е с @abstractmethod над него и pass в тялото. Python не дава да се създаде обект от клас, който още има абстрактен метод без тяло:
class Comet(SpaceObject): pass
try: comet = Comet("Халей", 0, 0, 0, 0)except TypeError: print("TypeError: Comet няма get_kind и не може да стане обект")TypeError: Comet няма get_kind и не може да стане обектЗвездата е най-простият наследник:
class Star extends OrbitableSpaceObject { public Star(String name, double coordinateX, double coordinateY, double coordinateZ, double mass) { super(name, coordinateX, coordinateY, coordinateZ, mass); }
@Override public String getKind() { return "Звезда"; }}class Star : OrbitableSpaceObject{ public Star(string name, double coordinateX, double coordinateY, double coordinateZ, double mass) : base(name, coordinateX, coordinateY, coordinateZ, mass) { }
public override string GetKind() { return "Звезда"; }}class Star(OrbitableSpaceObject): def get_kind(self): return "Звезда"class Star extends OrbitableSpaceObject { getKind() { return "Звезда"; }}Конструкторът се наследява: Star(...) вика този на родителя със същите аргументи. Затова Star пише само вида си.
Трите вида обекти в един списък от SpaceObject. Цикълът не знае кой какъв е, а всеки казва вида си:
SpaceObject[] objects = { new Star("Слънце", 0, 0, 0, 333000), new Planet("Земя", 149.6, 0, 0, 1), new Satellite("Луна", 150, 0, 0, 0.012),};for (SpaceObject object : objects) { object.displayInfo();}Звезда Слънце: (0.0, 0.0, 0.0), маса 333000.00Планета Земя: (149.6, 0.0, 0.0), маса 1.00Спътник Луна: (150.0, 0.0, 0.0), маса 0.01SpaceObject[] objects ={ new Star("Слънце", 0, 0, 0, 333000), new Planet("Земя", 149.6, 0, 0, 1), new Satellite("Луна", 150, 0, 0, 0.012),};foreach (SpaceObject spaceObject in objects){ spaceObject.DisplayInfo();}Звезда Слънце: (0.0, 0.0, 0.0), маса 333000.00Планета Земя: (149.6, 0.0, 0.0), маса 1.00Спътник Луна: (150.0, 0.0, 0.0), маса 0.01objects = [ Star("Слънце", 0, 0, 0, 333000), Planet("Земя", 149.6, 0, 0, 1), Satellite("Луна", 150, 0, 0, 0.012),]for space_object in objects: space_object.display_info()Звезда Слънце: (0.0, 0.0, 0.0), маса 333000.00Планета Земя: (149.6, 0.0, 0.0), маса 1.00Спътник Луна: (150.0, 0.0, 0.0), маса 0.01const objects = [ new Star("Слънце", 0, 0, 0, 333000), new Planet("Земя", 149.6, 0, 0, 1), new Satellite("Луна", 150, 0, 0, 0.012),];for (const spaceObject of objects) { spaceObject.displayInfo();}Звезда Слънце: (0.0, 0.0, 0.0), маса 333000.00Планета Земя: (149.6, 0.0, 0.0), маса 1.00Спътник Луна: (150.0, 0.0, 0.0), маса 0.01Идеята
Около кого се обикаля
Около звездата обикалят планети, около планетата обикалят спътници. И звездата, и планетата трябва да помнят кой обикаля около тях. Това е OrbitableSpaceObject: абстрактен клас между SpaceObject и тях.
abstract class OrbitableSpaceObject extends SpaceObject { private SpaceObject[] orbiters = new SpaceObject[10]; private int orbiterCount = 0;
public OrbitableSpaceObject(String name, double coordinateX, double coordinateY, double coordinateZ, double mass) { super(name, coordinateX, coordinateY, coordinateZ, mass); }
public void addOrbiter(SpaceObject orbiter) { if (orbiterCount == orbiters.length) { throw new IllegalStateException("Около " + getName() + " вече обикалят " + orbiters.length + " обекта"); } orbiters[orbiterCount] = orbiter; orbiterCount++; }
public SpaceObject[] getOrbiters() { SpaceObject[] result = new SpaceObject[orbiterCount]; for (int i = 0; i < orbiterCount; i++) { result[i] = orbiters[i]; } return result; }}abstract class OrbitableSpaceObject : SpaceObject{ private SpaceObject[] orbiters = new SpaceObject[10]; private int orbiterCount = 0;
public OrbitableSpaceObject(string name, double coordinateX, double coordinateY, double coordinateZ, double mass) : base(name, coordinateX, coordinateY, coordinateZ, mass) { }
public void AddOrbiter(SpaceObject orbiter) { if (orbiterCount == orbiters.Length) { throw new InvalidOperationException("Около " + Name + " вече обикалят " + orbiters.Length + " обекта"); } orbiters[orbiterCount] = orbiter; orbiterCount++; }
public SpaceObject[] GetOrbiters() { SpaceObject[] result = new SpaceObject[orbiterCount]; for (int i = 0; i < orbiterCount; i++) { result[i] = orbiters[i]; } return result; }}class OrbitableSpaceObject(SpaceObject): CAPACITY = 10
def __init__(self, name, coordinate_x, coordinate_y, coordinate_z, mass): super().__init__(name, coordinate_x, coordinate_y, coordinate_z, mass) self._orbiters = []
def add_orbiter(self, orbiter): if len(self._orbiters) == self.CAPACITY: raise RuntimeError(f"Около {self.name} вече обикалят {self.CAPACITY} обекта") self._orbiters.append(orbiter)
def get_orbiters(self): return list(self._orbiters)class OrbitableSpaceObject extends SpaceObject { static CAPACITY = 10; #orbiters = [];
addOrbiter(orbiter) { if (this.#orbiters.length === OrbitableSpaceObject.CAPACITY) { throw new Error(`Около ${this.name} вече обикалят ${OrbitableSpaceObject.CAPACITY} обекта`); } this.#orbiters.push(orbiter); }
getOrbiters() { return [...this.#orbiters]; }}- Обикалящите са в списък, който расте сам. Брояч не трябва:
len(self._orbiters)казва колко са. - Около една звезда има място за 10 обекта:
CAPACITYе на класа, общ за всички обекти от него. Ако мястото се запълни,add_orbiterхвърляRuntimeError: готовото изключение, когато действието не става в този момент. get_orbiters()връща копие на списъка.
По-точно, за любопитните
get_orbiters()връща копие, а не самия списък. Иначе код отвън може да добави сappendи да заобиколи проверката за място.StarнаследяваOrbitableSpaceObject, а не направоSpaceObject. Така звездата получава и обикалящите, и всичко отSpaceObject.
Копието се вижда в изхода: добавеното в него не стига до звездата.
sun = Star("Слънце", 0, 0, 0, 333000)Planet("Земя", 149.6, 0, 0, 1).orbit(sun)copy = sun.get_orbiters()copy.append(Planet("Марс", 227.9, 0, 0, 0.11))print(len(copy), len(sun.get_orbiters()))Земя обикаля около Слънце2 1Идеята
Правилото за орбитите
Планета обикаля около звезда. Спътник обикаля около планета. Всичко друго е невалидно. Обектите, които могат да обикалят, имат общ договор:
interface Orbiter { void orbit(SpaceObject target) throws NotValidSpaceObjectException;}interface Orbiter{ void Orbit(SpaceObject target);}class Orbiter(ABC): @abstractmethod def orbit(self, target): pass// Договорът Orbiter: обектът има метод orbit(target), който го пуска да обикаля// около target или хвърля NotValidSpaceObjectError.// JavaScript няма interface: Planet и Satellite просто имат такъв метод.Python няма отделна дума за интерфейс. Договорът е абстрактен клас само с абстрактни методи, а класът, който го изпълнява, го наследява до родителя си: class Planet(OrbitableSpaceObject, Orbiter). Python позволява да наследиш няколко класа наведнъж.
Ако правилото е нарушено, orbit хвърля свое изключение. Името казва точно какво е станало:
class NotValidSpaceObjectException extends Exception { public NotValidSpaceObjectException(String message) { super(message); }}class NotValidSpaceObjectException : Exception{ public NotValidSpaceObjectException(string message) : base(message) { }}class NotValidSpaceObjectError(Exception): passclass NotValidSpaceObjectError extends Error { constructor(message) { super(message); this.name = "NotValidSpaceObjectError"; }}Ето как го пази планетата:
@Overridepublic void orbit(SpaceObject target) throws NotValidSpaceObjectException { if (target instanceof Star star) { star.addOrbiter(this); System.out.println(getName() + " обикаля около " + star.getName()); } else { throw new NotValidSpaceObjectException(getName() + " не може да обикаля около " + target.getName() + ": планета обикаля само звезда"); }}public void Orbit(SpaceObject target){ if (target is Star star) { star.AddOrbiter(this); Console.WriteLine(Name + " обикаля около " + star.Name); } else { throw new NotValidSpaceObjectException(Name + " не може да обикаля около " + target.Name + ": планета обикаля само звезда"); }}def orbit(self, target): if isinstance(target, Star): target.add_orbiter(self) print(f"{self.name} обикаля около {target.name}") else: raise NotValidSpaceObjectError(f"{self.name} не може да обикаля около {target.name}: планета обикаля само звезда")orbit(target) { if (target instanceof Star) { target.addOrbiter(this); console.log(`${this.name} обикаля около ${target.name}`); } else { throw new NotValidSpaceObjectError(`${this.name} не може да обикаля около ${target.name}: планета обикаля само звезда`); }}isinstance(target, Star)проверява типа. След проверкатаtargetсе ползва като звезда: нова променлива не трябва.- Ако проверката не мине, изключението спира метода. Планетата не се добавя никъде.
Satelliteима същияorbit, само че проверява заPlanet.
По-точно, за любопитните
В Python никой не следи кой какво хвърля. Нито договорът, нито orbit казват, че може да хвърли, и никой не кара викащия да го хване. Програмата ще спре, ако никой не го хване, затова в играта винаги го хващаме. Името на изключението завършва на Error, както при вградените (ValueError).
Виж го
Кой около кого
sun = Star("Слънце", 0, 0, 0, 333000)earth = Planet("Земя", 149.6, 0, 0, 1)moon = Satellite("Луна", 150, 0, 0, 0.012)try_orbit(earth, sun)try_orbit(moon, earth)try_orbit(moon, sun)Стъпка по стъпка, с думи
- Три обекта: звезда, планета и спътник, всеки със свои координати и маса.
- Планета около звезда: правилото го позволява, Земята тръгва по орбитата.
- Спътник около планета: позволено. Луната обикаля Земята и се движи с нея.
- Спътник около звезда: orbit хвърля NotValidSpaceObjectError, а except в try_orbit печата защо.
Земята минава проверката на звездата и се добавя към обикалящите я. Луната минава проверката на Земята. Когато Луната опита да обикаля около Слънцето, проверката за Planet не минава. orbit хвърля и Луната остава около Земята.
Изключението се хваща в малка помощна функция. Тя пробва орбитата и при отказ казва защо:
static void tryOrbit(Orbiter orbiter, SpaceObject target) { try { orbiter.orbit(target); } catch (NotValidSpaceObjectException e) { System.out.println("Отказано: " + e.getMessage()); }}static void TryOrbit(Orbiter orbiter, SpaceObject target){ try { orbiter.Orbit(target); } catch (NotValidSpaceObjectException e) { Console.WriteLine("Отказано: " + e.Message); }}def try_orbit(orbiter, target): try: orbiter.orbit(target) except NotValidSpaceObjectError as e: print(f"Отказано: {e}")function tryOrbit(orbiter, target) { try { orbiter.orbit(target); } catch (e) { if (!(e instanceof NotValidSpaceObjectError)) { throw e; } console.log(`Отказано: ${e.message}`); }}Пробвай
Колко обикалят?
Марс опитва да обикаля около Земята.
Какво ще отпечата програмата?
def try_orbit(orbiter, target): try: orbiter.orbit(target) except NotValidSpaceObjectError as e: print(f"Отказано: {e}")
sun = Star("Слънце", 0, 0, 0, 333000)earth = Planet("Земя", 149.6, 0, 0, 1)mars = Planet("Марс", 227.9, 0, 0, 0.11)moon = Satellite("Луна", 150, 0, 0, 0.012)try_orbit(earth, sun)try_orbit(mars, earth)try_orbit(moon, earth)print(f"Около Слънце: {len(sun.get_orbiters())}")print(f"Около Земя: {len(earth.get_orbiters())}")Марс не минава проверката за Star и не се добавя никъде. Помощната функция хваща отказа, затова програмата продължава с Луната. Около Слънцето е само Земята, около Земята е само Луната.
Идеята
Кораб, който лети
Корабите не обикалят, а летят от обект до обект. Това е друг договор:
interface Fly { void flyTo(SpaceObject destination) throws NotValidSpaceObjectException;}interface Fly{ void FlyTo(SpaceObject destination);}class Fly(ABC): @abstractmethod def fly_to(self, destination): pass// Договорът Fly: обектът има метод flyTo(destination), който го мести при destination// или хвърля NotValidSpaceObjectError.SpaceShip наследява SpaceObject и изпълнява Fly. До звезда не може да лети. До всичко друго лети и взима координатите на целта:
@Overridepublic void flyTo(SpaceObject destination) throws NotValidSpaceObjectException { if (destination instanceof Star) { throw new NotValidSpaceObjectException(getName() + " не може да лети до " + destination.getName() + ": звездата ще го изгори"); } moveTo(destination.getCoordinateX(), destination.getCoordinateY(), destination.getCoordinateZ()); System.out.println(getName() + " пристигна при " + destination.getName());}public void FlyTo(SpaceObject destination){ if (destination is Star) { throw new NotValidSpaceObjectException(Name + " не може да лети до " + destination.Name + ": звездата ще го изгори"); } MoveTo(destination.CoordinateX, destination.CoordinateY, destination.CoordinateZ); Console.WriteLine(Name + " пристигна при " + destination.Name);}def fly_to(self, destination): if isinstance(destination, Star): raise NotValidSpaceObjectError(f"{self.name} не може да лети до {destination.name}: звездата ще го изгори") self._move_to(destination.coordinate_x, destination.coordinate_y, destination.coordinate_z) print(f"{self.name} пристигна при {destination.name}")flyTo(destination) { if (destination instanceof Star) { throw new NotValidSpaceObjectError(`${this.name} не може да лети до ${destination.name}: звездата ще го изгори`); } this._moveTo(destination.coordinateX, destination.coordinateY, destination.coordinateZ); console.log(`${this.name} пристигна при ${destination.name}`);}SpaceShip ship = new SpaceShip("Скиталец", 149.6, 0, 0, 0);Planet mars = new Planet("Марс", 227.9, 0, 0, 0.11);Star sun = new Star("Слънце", 0, 0, 0, 333000);try { ship.flyTo(mars); ship.displayInfo(); ship.flyTo(sun); ship.displayInfo();} catch (NotValidSpaceObjectException e) { System.out.println("Отказано: " + e.getMessage());}Скиталец пристигна при МарсКораб Скиталец: (227.9, 0.0, 0.0), маса 0.00Отказано: Скиталец не може да лети до Слънце: звездата ще го изгориSpaceShip ship = new SpaceShip("Скиталец", 149.6, 0, 0, 0);Planet mars = new Planet("Марс", 227.9, 0, 0, 0.11);Star sun = new Star("Слънце", 0, 0, 0, 333000);try{ ship.FlyTo(mars); ship.DisplayInfo(); ship.FlyTo(sun); ship.DisplayInfo();}catch (NotValidSpaceObjectException e){ Console.WriteLine("Отказано: " + e.Message);}Скиталец пристигна при МарсКораб Скиталец: (227.9, 0.0, 0.0), маса 0.00Отказано: Скиталец не може да лети до Слънце: звездата ще го изгориship = SpaceShip("Скиталец", 149.6, 0, 0, 0)mars = Planet("Марс", 227.9, 0, 0, 0.11)sun = Star("Слънце", 0, 0, 0, 333000)try: ship.fly_to(mars) ship.display_info() ship.fly_to(sun) ship.display_info()except NotValidSpaceObjectError as e: print(f"Отказано: {e}")Скиталец пристигна при МарсКораб Скиталец: (227.9, 0.0, 0.0), маса 0.00Отказано: Скиталец не може да лети до Слънце: звездата ще го изгориconst ship = new SpaceShip("Скиталец", 149.6, 0, 0, 0);const mars = new Planet("Марс", 227.9, 0, 0, 0.11);const sun = new Star("Слънце", 0, 0, 0, 333000);try { ship.flyTo(mars); ship.displayInfo(); ship.flyTo(sun); ship.displayInfo();} catch (e) { if (!(e instanceof NotValidSpaceObjectError)) { throw e; } console.log(`Отказано: ${e.message}`);}Скиталец пристигна при МарсКораб Скиталец: (227.9, 0.0, 0.0), маса 0.00Отказано: Скиталец не може да лети до Слънце: звездата ще го изгориВторият display_info() не се изпълнява: изключението прескача до except.
По-точно, за любопитните
class Probe(SpaceObject, Orbiter, Fly).Пробвай
Намери грешката
Луната обикаля около Слънцето, а не трябва. На кой ред в orbit на спътника е грешката?
Избери реда с грешката.
OrbitableSpaceObject е родител и на Planet, и на Star. Проверката пуска и двете. Трябва да е isinstance(target, Planet): спътник обикаля само планета.
Упражнение
Космосът в код
Реши задачите в редактора си, с класовете от урока.
1. Слънчевата система. Опиши осемте планети с три списъка: имена, разстояния от Слънцето (милиони км) и маси (земни маси). В цикъл създай всяка планета на x = разстоянието и я накарай да обикаля около Слънцето. После покажи всички обикалящи.
| Планета | Разстояние | Маса |
|---|---|---|
| Меркурий | 57,9 | 0,06 |
| Венера | 108,2 | 0,82 |
| Земя | 149,6 | 1 |
| Марс | 227,9 | 0,11 |
| Юпитер | 778,5 | 317,8 |
| Сатурн | 1432 | 95,2 |
| Уран | 2867 | 14,5 |
| Нептун | 4515 | 17,1 |
Меркурий обикаля около СлънцеВенера обикаля около СлънцеЗемя обикаля около СлънцеМарс обикаля около СлънцеЮпитер обикаля около СлънцеСатурн обикаля около СлънцеУран обикаля около СлънцеНептун обикаля около СлънцеОколо Слънце обикалят 8 планети:Планета Меркурий: (57.9, 0.0, 0.0), маса 0.06Планета Венера: (108.2, 0.0, 0.0), маса 0.82Планета Земя: (149.6, 0.0, 0.0), маса 1.00Планета Марс: (227.9, 0.0, 0.0), маса 0.11Планета Юпитер: (778.5, 0.0, 0.0), маса 317.80Планета Сатурн: (1432.0, 0.0, 0.0), маса 95.20Планета Уран: (2867.0, 0.0, 0.0), маса 14.50Планета Нептун: (4515.0, 0.0, 0.0), маса 17.102. Разстояние. Напиши def distance(a, b) с теоремата на Питагор в три измерения: корен от сбора на квадратите на разликите по x, y и z. Земята е в (149,6; 0; 0), Марс е в (0; 227,9; 0), Луната е в (149,6; 0,4; 0), а Слънцето е в началото.
Земя – Марс: 272.6 млн. кмЗемя – Луна: 0.4 млн. кмСлънце – Марс: 227.9 млн. км3. Цялото дърво. Промени display_info така, че звездата да показва и планетите си, а всяка планета и спътниците си, с два интервала отстъп на ниво. Подсказка: параметър за отстъпа със стойност по подразбиране, indent="", за да става и извикването без аргумент. OrbitableSpaceObject презаписва метода и вика родителя. Земята и Марс обикалят Слънцето, Луната обикаля Земята, Фобос обикаля Марс.
Земя обикаля около СлънцеМарс обикаля около СлънцеЛуна обикаля около ЗемяФобос обикаля около МарсЗвезда Слънце: (0.0, 0.0, 0.0), маса 333000.00 Планета Земя: (149.6, 0.0, 0.0), маса 1.00 Спътник Луна: (150.0, 0.0, 0.0), маса 0.01 Планета Марс: (227.9, 0.0, 0.0), маса 0.11 Спътник Фобос: (227.9, 0.0, 0.0), маса 0.00Още задачи
- Двоен опит. Сега Земята може да се добави два пъти към обикалящите Слънцето. Направи така, че втори опит да хвърля
NotValidSpaceObjectError. - Пълна звезда. Добави 11 планети към една звезда и хвани изключението при единадесетата.
- Сонда. Направи
Probe, която и обикаля, и лети (виж „По-точно“ при корабите).
Тест