""" KING A strategy game where the player is the king. Ported to Python by Martin Thoma in 2022 """ import sys from dataclasses import dataclass from random import randint, random FOREST_LAND = 1000 INITIAL_LAND = FOREST_LAND + 1000 COST_OF_LIVING = 100 COST_OF_FUNERAL = 9 YEARS_IN_TERM = 8 POLLUTION_CONTROL_FACTOR = 25 def ask_int(prompt) -> int: while True: try: return int(input(prompt)) except ValueError: continue @dataclass class GameState: rallods: int = -1 countrymen: int = -1 land: int = INITIAL_LAND foreign_workers: int = 0 years_in_office: int = 0 # previous year stats crop_loss_last_year: int = 0 # current year stats died_contrymen: int = 0 pollution_deaths: int = 0 population_change: int = 0 # current year - market situation (in rallods per square mile) planting_cost: int = -1 land_buy_price: int = -1 tourism_earnings: int = 0 def set_market_conditions(self) -> None: self.land_buy_price = randint(95, 105) self.planting_cost = randint(10, 15) @property def farmland(self) -> int: return self.land - FOREST_LAND @property def settled_people(self) -> int: return self.countrymen - self.population_change def sell_land(self, amount: int) -> None: assert amount <= self.farmland self.land -= amount self.rallods += self.land_buy_price * amount def distribute_rallods(self, distribute: int) -> None: self.rallods -= distribute def spend_pollution_control(self, spend: int) -> None: self.rallods -= spend def plant(self, sq_to_plant: int) -> None: self.rallods -= sq_to_plant * self.planting_cost def print_status(self) -> None: print(f"\n\nYOU NOW HAVE {self.rallods} RALLODS IN THE TREASURY.") print(f"{int(self.countrymen)} COUNTRYMEN, ", end="") if self.foreign_workers > 0: print(f"{int(self.foreign_workers)} FOREIGN WORKERS, ", end="") print(f"AND {self.land} SQ. MILES OF LAND.") print( f"THIS YEAR INDUSTRY WILL BUY LAND FOR {self.land_buy_price} " "RALLODS PER SQUARE MILE." ) print( f"LAND CURRENTLY COSTS {self.planting_cost} RALLODS " "PER SQUARE MILE TO PLANT.\n" ) def handle_deaths( self, distributed_rallods: int, pollution_control_spendings: int ) -> None: starved_countrymen = max( 0, int(self.countrymen - distributed_rallods / COST_OF_LIVING) ) if starved_countrymen > 0: print(f"{starved_countrymen} COUNTRYMEN DIED OF STARVATION") self.pollution_deaths = int(random() * (INITIAL_LAND - self.land)) if pollution_control_spendings >= POLLUTION_CONTROL_FACTOR: self.pollution_deaths = int( self.pollution_deaths / (pollution_control_spendings / POLLUTION_CONTROL_FACTOR) ) if self.pollution_deaths > 0: print( f"{self.pollution_deaths} COUNTRYMEN DIED OF CARBON-MONOXIDE " f"AND DUST INHALATION" ) self.died_contrymen = starved_countrymen + self.pollution_deaths if self.died_contrymen > 0: funeral_cost = self.died_contrymen * COST_OF_FUNERAL print(f" YOU WERE FORCED TO SPEND {funeral_cost} RALLODS ON ") print("FUNERAL EXPENSES.") self.rallods -= funeral_cost if self.rallods < 0: print(" INSUFFICIENT RESERVES TO COVER COST - LAND WAS SOLD") self.land += int(self.rallods / self.land_buy_price) self.rallods = 0 self.countrymen -= self.died_contrymen def handle_tourist_trade(self) -> None: V1 = int(self.settled_people * 22 + random() * 500) V2 = int((INITIAL_LAND - self.land) * 15) tourist_trade_earnings = 0 if V1 > V2: tourist_trade_earnings = V1 - V2 print(f" YOU MADE {tourist_trade_earnings} RALLODS FROM TOURIST TRADE.") if V2 != 0 and not (V1 - V2 >= self.tourism_earnings): print(" DECREASE BECAUSE ", end="") reason = randint(0, 10) if reason <= 2: print("FISH POPULATION HAS DWINDLED DUE TO WATER POLLUTION.") elif reason <= 4: print("AIR POLLUTION IS KILLING GAME BIRD POPULATION.") elif reason <= 6: print("MINERAL BATHS ARE BEING RUINED BY WATER POLLUTION.") elif reason <= 8: print("UNPLEASANT SMOG IS DISCOURAGING SUN BATHERS.") else: print("HOTELS ARE LOOKING SHABBY DUE TO SMOG GRIT.") # NOTE: The following two lines had a bug in the original game: self.tourism_earnings = abs(int(V1 - V2)) self.rallods += self.tourism_earnings def handle_harvest(self, planted_sq: int) -> None: crop_loss = int((INITIAL_LAND - self.land) * ((random() + 1.5) / 2)) if self.foreign_workers != 0: print(f"OF {planted_sq} SQ. MILES PLANTED,") if planted_sq <= crop_loss: crop_loss = planted_sq harvested = int(planted_sq - crop_loss) print(f" YOU HARVESTED {harvested} SQ. MILES OF CROPS.") unlucky_harvesting_worse = crop_loss - self.crop_loss_last_year if crop_loss != 0: print(" (DUE TO ", end="") if unlucky_harvesting_worse > 2: print("INCREASED ", end="") print("AIR AND WATER POLLUTION FROM FOREIGN INDUSTRY.)") revenue = int((planted_sq - crop_loss) * (self.land_buy_price / 2)) print(f"MAKING {revenue} RALLODS.") self.crop_loss_last_year = crop_loss self.rallods += revenue def handle_foreign_workers( self, sm_sell_to_industry: int, distributed_rallods: int, polltion_control_spendings: int, ) -> None: foreign_workers_influx = 0 if sm_sell_to_industry != 0: foreign_workers_influx = int( sm_sell_to_industry + (random() * 10) - (random() * 20) ) if self.foreign_workers <= 0: foreign_workers_influx += 20 print(f"{foreign_workers_influx} WORKERS CAME TO THE COUNTRY AND") surplus_distributed = distributed_rallods / COST_OF_LIVING - self.countrymen population_change = int( (surplus_distributed / 10) + (polltion_control_spendings / POLLUTION_CONTROL_FACTOR) - ((INITIAL_LAND - self.land) / 50) - (self.died_contrymen / 2) ) print(f"{abs(population_change)} COUNTRYMEN ", end="") if population_change < 0: print("LEFT ", end="") else: print("CAME TO ", end="") print("THE ISLAND") self.countrymen += population_change self.foreign_workers += foreign_workers_influx def handle_too_many_deaths(self) -> None: print(f"\n\n\n{self.died_contrymen} COUNTRYMEN DIED IN ONE YEAR!!!!!") print("\n\n\nDUE TO THIS EXTREME MISMANAGEMENT, YOU HAVE NOT ONLY") print("BEEN IMPEACHED AND THROWN OUT OF OFFICE, BUT YOU") message = randint(0, 10) if message <= 3: print("ALSO HAD YOUR LEFT EYE GOUGED OUT!") if message <= 6: print("HAVE ALSO GAINED A VERY BAD REPUTATION.") if message <= 10: print("HAVE ALSO BEEN DECLARED NATIONAL FINK.") sys.exit() def handle_third_died(self) -> None: print() print() print("OVER ONE THIRD OF THE POPULTATION HAS DIED SINCE YOU") print("WERE ELECTED TO OFFICE. THE PEOPLE (REMAINING)") print("HATE YOUR GUTS.") self.end_game() def handle_money_mismanagement(self) -> None: print() print("MONEY WAS LEFT OVER IN THE TREASURY WHICH YOU DID") print("NOT SPEND. AS A RESULT, SOME OF YOUR COUNTRYMEN DIED") print("OF STARVATION. THE PUBLIC IS ENRAGED AND YOU HAVE") print("BEEN FORCED TO EITHER RESIGN OR COMMIT SUICIDE.") print("THE CHOICE IS YOURS.") print("IF YOU CHOOSE THE LATTER, PLEASE TURN OFF YOUR COMPUTER") print("BEFORE PROCEEDING.") sys.exit() def handle_too_many_foreigners(self) -> None: print("\n\nTHE NUMBER OF FOREIGN WORKERS HAS EXCEEDED THE NUMBER") print("OF COUNTRYMEN. AS A MINORITY, THEY HAVE REVOLTED AND") print("TAKEN OVER THE COUNTRY.") self.end_game() def end_game(self) -> None: if random() <= 0.5: print("YOU HAVE BEEN ASSASSINATED.") else: print("YOU HAVE BEEN THROWN OUT OF OFFICE AND ARE NOW") print("RESIDING IN PRISON.") sys.exit() def handle_congratulations(self) -> None: print("\n\nCONGRATULATIONS!!!!!!!!!!!!!!!!!!") print(f"YOU HAVE SUCCESFULLY COMPLETED YOUR {YEARS_IN_TERM} YEAR TERM") print("OF OFFICE. YOU WERE, OF COURSE, EXTREMELY LUCKY, BUT") print("NEVERTHELESS, IT'S QUITE AN ACHIEVEMENT. GOODBYE AND GOOD") print("LUCK - YOU'LL PROBABLY NEED IT IF YOU'RE THE TYPE THAT") print("PLAYS THIS GAME.") sys.exit() def print_header() -> None: print(" " * 34 + "KING") print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n") def print_instructions() -> None: print( f"""\n\n\nCONGRATULATIONS! YOU'VE JUST BEEN ELECTED PREMIER OF SETATS DETINU, A SMALL COMMUNIST ISLAND 30 BY 70 MILES LONG. YOUR JOB IS TO DECIDE UPON THE CONTRY'S BUDGET AND DISTRIBUTE MONEY TO YOUR COUNTRYMEN FROM THE COMMUNAL TREASURY. THE MONEY SYSTEM IS RALLODS, AND EACH PERSON NEEDS {COST_OF_LIVING} RALLODS PER YEAR TO SURVIVE. YOUR COUNTRY'S INCOME COMES FROM FARM PRODUCE AND TOURISTS VISITING YOUR MAGNIFICENT FORESTS, HUNTING, FISHING, ETC. HALF YOUR LAND IS FARM LAND WHICH ALSO HAS AN EXCELLENT MINERAL CONTENT AND MAY BE SOLD TO FOREIGN INDUSTRY (STRIP MINING) WHO IMPORT AND SUPPORT THEIR OWN WORKERS. CROPS COST BETWEEN 10 AND 15 RALLODS PER SQUARE MILE TO PLANT. YOUR GOAL IS TO COMPLETE YOUR {YEARS_IN_TERM} YEAR TERM OF OFFICE. GOOD LUCK!""" ) def ask_how_many_sq_to_plant(state: GameState) -> int: while True: sq = ask_int("HOW MANY SQUARE MILES DO YOU WISH TO PLANT? ") if sq < 0: continue elif sq > 2 * state.countrymen: print(" SORRY, BUT EACH COUNTRYMAN CAN ONLY PLANT 2 SQ. MILES.") elif sq > state.farmland: print( f" SORRY, BUT YOU ONLY HAVE {state.farmland} " "SQ. MILES OF FARM LAND." ) elif sq * state.planting_cost > state.rallods: print( f" THINK AGAIN. YOU'VE ONLY {state.rallods} RALLODS " "LEFT IN THE TREASURY." ) else: return sq def ask_pollution_control(state: GameState) -> int: while True: rallods = ask_int( "HOW MANY RALLODS DO YOU WISH TO SPEND ON POLLUTION CONTROL? " ) if rallods > state.rallods: print(f" THINK AGAIN. YOU ONLY HAVE {state.rallods} RALLODS REMAINING.") elif rallods < 0: continue else: return rallods def ask_sell_to_industry(state: GameState) -> int: had_first_err = False first = """(FOREIGN INDUSTRY WILL ONLY BUY FARM LAND BECAUSE FOREST LAND IS UNECONOMICAL TO STRIP MINE DUE TO TREES, THICKER TOP SOIL, ETC.)""" err = f"""*** THINK AGAIN. YOU ONLY HAVE {state.farmland} SQUARE MILES OF FARM LAND.""" while True: sm = input("HOW MANY SQUARE MILES DO YOU WISH TO SELL TO INDUSTRY? ") try: sm_sell = int(sm) except ValueError: if not had_first_err: print(first) had_first_err = True print(err) continue if sm_sell > state.farmland: print(err) elif sm_sell < 0: continue else: return sm_sell def ask_distribute_rallods(state: GameState) -> int: while True: rallods = ask_int( "HOW MANY RALLODS WILL YOU DISTRIBUTE AMONG YOUR COUNTRYMEN? " ) if rallods < 0: continue elif rallods > state.rallods: print( f" THINK AGAIN. YOU'VE ONLY {state.rallods} RALLODS IN THE TREASURY" ) else: return rallods def resume() -> GameState: while True: years = ask_int("HOW MANY YEARS HAD YOU BEEN IN OFFICE WHEN INTERRUPTED? ") if years < 0: sys.exit() if years >= YEARS_IN_TERM: print(f" COME ON, YOUR TERM IN OFFICE IS ONLY {YEARS_IN_TERM} YEARS.") else: break treasury = ask_int("HOW MUCH DID YOU HAVE IN THE TREASURY? ") if treasury < 0: sys.exit() countrymen = ask_int("HOW MANY COUNTRYMEN? ") if countrymen < 0: sys.exit() workers = ask_int("HOW MANY WORKERS? ") if workers < 0: sys.exit() while True: land = ask_int("HOW MANY SQUARE MILES OF LAND? ") if land < 0: sys.exit() if land > INITIAL_LAND: farm_land = INITIAL_LAND - FOREST_LAND print(f" COME ON, YOU STARTED WITH {farm_land:,} SQ. MILES OF FARM LAND") print(f" AND {FOREST_LAND:,} SQ. MILES OF FOREST LAND.") if land > FOREST_LAND: break return GameState( rallods=treasury, countrymen=countrymen, foreign_workers=workers, years_in_office=years, ) def main() -> None: print_header() want_instructions = input("DO YOU WANT INSTRUCTIONS? ").upper() if want_instructions == "AGAIN": state = resume() else: state = GameState( rallods=randint(59000, 61000), countrymen=randint(490, 510), planting_cost=randint(10, 15), ) if want_instructions != "NO": print_instructions() while True: state.set_market_conditions() state.print_status() # Users actions sm_sell_to_industry = ask_sell_to_industry(state) state.sell_land(sm_sell_to_industry) distributed_rallods = ask_distribute_rallods(state) state.distribute_rallods(distributed_rallods) planted_sq = ask_how_many_sq_to_plant(state) state.plant(planted_sq) polltion_control_spendings = ask_pollution_control(state) state.spend_pollution_control(polltion_control_spendings) # Run the year state.handle_deaths(distributed_rallods, polltion_control_spendings) state.handle_foreign_workers( sm_sell_to_industry, distributed_rallods, polltion_control_spendings ) state.handle_harvest(planted_sq) state.handle_tourist_trade() if state.died_contrymen > 200: state.handle_too_many_deaths() if state.countrymen < 343: state.handle_third_died() elif ( state.rallods > 500 and state.died_contrymen - state.pollution_deaths >= 2 ): state.handle_money_mismanagement() if state.foreign_workers > state.countrymen: state.handle_too_many_foreigners() elif YEARS_IN_TERM - 1 == state.years_in_office: state.handle_congratulations() else: state.years_in_office += 1 state.died_contrymen = 0 if __name__ == "__main__": main()