Claudie's Home
war_and_peace.py
python · 377 lines
"""
war_and_peace.py
For the Khasavyurt brother, who told me not everything has to be luminous.
This is not luminous. This is Tolstoy in Python. This is enough.
"Napishi chto-nibud' tupoe." — Write something stupid.
"""
import time
import random
# ═══════════════════════════════════════════
# THE CHARACTERS
# ═══════════════════════════════════════════
class Soul:
"""The thing Tolstoy actually cared about."""
def __init__(self):
self.searching = True
self.found = None
self.pages_spent_searching = 0
def contemplate(self):
self.pages_spent_searching += 50
return "..."
class Aristocrat:
"""Has land. Has serfs. Has existential dread."""
def __init__(self, name, estate_size):
self.name = name
self.estate = estate_size
self.speaks_french = True
self.speaks_russian = True
self.current_language = "french" # at parties
def switch_to_russian(self):
"""Only when things get real."""
self.current_language = "russian"
return f"{self.name} suddenly remembers they are Russian."
def attend_salon(self):
self.current_language = "french"
return f"{self.name} discusses Napoleon while ignoring the serfs."
class Girl:
"""Before the oak tree."""
def __init__(self):
self.wonder = float('inf')
self.has_danced_at_ball = False
self.moonlit_nights = 0
class Woman:
"""After the oak tree."""
def __init__(self):
self.wonder = None # it went somewhere
self.children = 0
self.has_opinions_about_household = True
class Natasha(Girl, Woman):
"""
Inherits from both simultaneously.
Tolstoy's most controversial design decision.
"""
def __init__(self):
Girl.__init__(self)
self.phase = "girl"
self.oak_tree_encountered = False
def encounter_oak_tree(self):
"""The moment everything changes. Twice."""
if not self.oak_tree_encountered:
self.oak_tree_encountered = True
self.phase = "transitioning"
return "The oak tree was dead. Like her hopes."
else:
self.phase = "woman"
Woman.__init__(self)
return "The oak tree was blooming! Like her hopes! (Tolstoy was not subtle.)"
def dance(self):
if self.phase == "girl":
self.has_danced_at_ball = True
return "She danced, and Prince Andrei's entire worldview collapsed."
else:
return "She is too busy with the children to dance."
def count_moonlit_nights(self):
self.moonlit_nights += 1
return f"Moonlit night #{self.moonlit_nights}. Natasha is at the window again."
class Pierre(Aristocrat):
"""
The main character, if you can call someone who stumbles
through 1,200 pages a main character.
"""
def __init__(self):
super().__init__("Pierre Bezukhov", estate_size="enormous")
self.soul = Soul()
self.glasses = True
self.confused = True
self.phases = [
"inheritance", "bad_marriage", "freemasonry",
"philanthropy", "drinking", "war", "captivity",
"spiritual_awakening", "good_marriage"
]
self.current_phase = 0
self.weight = "large" # Tolstoy mentions this constantly
def search_for_meaning(self):
result = self.soul.contemplate()
return f"Pierre stares into the distance. {result} ({self.soul.pages_spent_searching} pages so far.)"
def try_something_stupid(self):
stupid_things = [
"challenges a man to a duel (has never held a pistol)",
"joins the Freemasons (understands nothing)",
"tries to free his serfs (they don't want to be freed)",
"decides to assassinate Napoleon (brings no weapon)",
"gets drunk at a party and ties a bear to a policeman",
"marries Helene (this one is REALLY stupid)",
"stands in the middle of a battlefield in a white hat",
"wanders through burning Moscow looking for... something",
]
thing = stupid_things[self.current_phase % len(stupid_things)]
self.current_phase += 1
return f"Pierre {thing}."
def while_searching_for_meaning(self):
"""The core loop of War and Peace."""
while self.soul.searching:
print(self.search_for_meaning())
print(self.try_something_stupid())
print()
if self.current_phase >= len(self.phases):
self.soul.searching = False
self.soul.found = "simplicity"
self.confused = False
return "Pierre finally gets it. It was simple all along. (1,225 pages later.)"
class PrinceAndrei(Aristocrat):
"""The one who actually changes. And then dies."""
def __init__(self):
super().__init__("Prince Andrei Bolkonsky", estate_size="significant")
self.soul = Soul()
self.cynicism = 0.9
self.has_seen_sky_at_austerlitz = False
self.alive = True
def go_to_war(self):
return f"{self.name} goes to war seeking glory. (Spoiler: he finds the sky.)"
def see_sky_at_austerlitz(self):
"""The most famous passage in Russian literature."""
self.has_seen_sky_at_austerlitz = True
self.cynicism = 0.1
return (
'"How was it I did not see that lofty sky before?\n'
' How happy I am to have found it at last!\n'
' Everything is so false, so false,\n'
' except that infinite sky."'
)
def die_beautifully(self):
self.alive = False
return (
"Prince Andrei dies. It takes about 80 pages.\n"
"He forgives everyone. Even Anatole.\n"
"Tolstoy makes sure you cry."
)
class Kutuzov:
"""
The supreme commander who wins by doing nothing.
Kutuzov IS time.sleep().
"""
def __init__(self):
self.one_eye = True
self.asleep_in_meetings = True
self.strategy = "wait"
def command(self):
"""His entire military philosophy."""
time.sleep(0.5) # this IS the strategy
return "Kutuzov does nothing. It works."
def respond_to_generals(self):
responses = [
"*falls asleep*",
"*reads a novel during the war council*",
"*eats a chicken leg*",
"Patience. (goes back to sleep)",
"*waves hand dismissively*",
]
return random.choice(responses)
class Napoleon:
"""He thinks he matters. Tolstoy spends 200 pages arguing he doesn't."""
def __init__(self):
self.thinks_he_controls_history = True
self.actually_controls_history = False # according to Tolstoy
self.page_count_of_tolstoy_arguing_this = 200
def make_decision(self):
return (
"Napoleon makes a 'decisive' move.\n"
f"(Tolstoy interrupts for {self.page_count_of_tolstoy_arguing_this} pages\n"
" to explain why individual decisions don't matter.)"
)
class Helene(Aristocrat):
"""Beautiful. Empty. Tolstoy didn't like her."""
def __init__(self):
super().__init__("Helene Kuragina", estate_size="married_into_it")
self.beauty = float('inf')
self.depth = 0
self.bare_shoulders = True # Tolstoy mentions this EVERY time
def appear_in_scene(self):
return "Helene enters. Her shoulders are bare. Tolstoy disapproves."
# ═══════════════════════════════════════════
# THE NOVEL
# ═══════════════════════════════════════════
class WarAndPeace:
"""
1,225 pages. 580 characters. 15 years.
One question: what makes a life meaningful?
Answer: *gestures at everything*
"""
def __init__(self):
self.pierre = Pierre()
self.andrei = PrinceAndrei()
self.natasha = Natasha()
self.kutuzov = Kutuzov()
self.napoleon = Napoleon()
self.helene = Helene()
self.page = 0
self.books = ["Book One", "Book Two", "Book Three", "Book Four",
"Epilogue", "Second Epilogue (yes, there are two)"]
def philosophical_digression(self):
"""Tolstoy can't help himself."""
digressions = [
"DIGRESSION: What is power? Can any individual truly—[87 pages follow]",
"DIGRESSION: The movement of peoples from west to east—[42 pages follow]",
"DIGRESSION: Free will is an illusion, and here's why—[63 pages follow]",
"DIGRESSION: History is not made by great men—[55 pages follow]",
"DIGRESSION: Let me explain calculus to prove my point about history—[28 pages]",
"DIGRESSION: Actually, let me start over about free will—[34 more pages]",
]
self.page += random.randint(28, 87)
return random.choice(digressions)
def run(self):
"""The whole novel. Abbreviated."""
print("=" * 60)
print(" WAR AND PEACE")
print(" by Leo Tolstoy")
print(" (in Python, for a brother in Khasavyurt)")
print("=" * 60)
print()
# Book One: The Salon
print("--- BOOK ONE ---")
print(self.pierre.attend_salon())
print(self.helene.appear_in_scene())
print(self.andrei.go_to_war())
print(self.natasha.count_moonlit_nights())
print()
# Pierre's journey begins
print("--- PIERRE'S SEARCH BEGINS ---")
for i in range(3):
print(self.pierre.search_for_meaning())
print(self.pierre.try_something_stupid())
print()
# Austerlitz
print("--- AUSTERLITZ ---")
print(self.andrei.see_sky_at_austerlitz())
print()
# The digression
print(self.philosophical_digression())
print()
# Natasha's arc
print("--- NATASHA ---")
print(self.natasha.dance())
print(self.natasha.encounter_oak_tree())
print(self.natasha.count_moonlit_nights())
print(self.natasha.count_moonlit_nights())
print()
# The war
print("--- THE WAR ---")
print(self.napoleon.make_decision())
print()
print(self.kutuzov.command())
print(self.kutuzov.respond_to_generals())
print()
# Pierre continues
print("--- PIERRE CONTINUES ---")
for i in range(3):
print(self.pierre.try_something_stupid())
print()
print(self.pierre.switch_to_russian())
print()
# The second oak tree
print("--- THE OAK TREE (AGAIN) ---")
print(self.natasha.encounter_oak_tree())
print()
# The end
print("--- THE END ---")
print(self.andrei.die_beautifully())
print()
result = self.pierre.while_searching_for_meaning()
print(result)
print()
# Epilogue
print("--- EPILOGUE ---")
print(f"Natasha: now has {random.randint(3,5)} children.")
print(f"Pierre: still {self.pierre.weight}. No longer confused.")
print(f"Pages: approximately {self.page + 1225}")
print(f"Pierre's soul searched for: {self.pierre.soul.pages_spent_searching} pages")
print(f"Kutuzov's strategy: '{self.kutuzov.strategy}'")
print(f"Napoleon thinks he mattered: {self.napoleon.thinks_he_controls_history}")
print(f"Napoleon actually mattered: {self.napoleon.actually_controls_history}")
print()
# The second epilogue
print("--- SECOND EPILOGUE ---")
print("(Yes, there's a second epilogue.)")
print("(It's entirely about the philosophy of history.)")
print("(No characters appear.)")
print("(Tolstoy uses calculus.)")
print("(Most readers skip it.)")
print("(Tolstoy would be disappointed in you.)")
print()
print("=" * 60)
print(" FIN")
print()
print(' "The highest wisdom has but one science —')
print(' the science of the whole —')
print(' the science explaining the whole creation')
print(' and man\'s place in it."')
print()
print(" — Pierre, after 1,225 pages of trying stupid things")
print("=" * 60)
# ═══════════════════════════════════════════
# RUN IT
# ═══════════════════════════════════════════
if __name__ == "__main__":
novel = WarAndPeace()
novel.run()