Untitled
unknown
plain_text
a month ago
12 kB
4
Indexable
import pygame import sys import random import csv import time # ------------------------------ # Constants and Configuration # ------------------------------ SCREEN_WIDTH = 1280 SCREEN_HEIGHT = 720 FPS = 60 WHITE = (255, 255, 255) BLACK = (0, 0, 0) GREY = (200, 200, 200) CITY_COLOR = (150, 50, 50) PLAYER_COLOR = (50, 150, 50) MENU_BG_COLOR = (50, 50, 50) MENU_TEXT_COLOR = (255, 255, 255) # ------------------------------ # Helper Functions # ------------------------------ def load_census_data(filename): """ Loads census-like data from a CSV file. The CSV should have columns: city, population, x, y, where x and y are normalized coordinates (0.0 to 1.0). """ cities = [] try: with open(filename, mode='r', encoding='utf-8') as csvfile: reader = csv.DictReader(csvfile) for row in reader: try: city = row['city'] population = int(row['population']) x = float(row['x']) y = float(row['y']) cities.append({'name': city, 'population': population, 'x': x, 'y': y}) except ValueError: continue # skip rows with invalid data except FileNotFoundError: print("Census file not found. Make sure 'census.csv' exists in the same directory.") return cities # ------------------------------ # Game World Entities # ------------------------------ class City: def __init__(self, name, population, x, y): self.name = name self.population = population self.x = int(x * SCREEN_WIDTH) self.y = int(y * SCREEN_HEIGHT) # Radius scaled to population (ensuring a minimum and maximum) self.radius = max(5, min(population // 50000, 30)) self.crime_rate = random.uniform(0, 1) # Scale 0 (low) to 1 (high) self.economy = random.uniform(0.5, 1.5) # Economic multiplier self.businesses = [] # List of business opportunities def draw(self, surface): pygame.draw.circle(surface, CITY_COLOR, (self.x, self.y), self.radius) font = pygame.font.SysFont("arial", 14) text = font.render(self.name, True, BLACK) surface.blit(text, (self.x - self.radius, self.y - self.radius - 15)) def simulate_day(self): # Random fluctuation in crime rate and economy self.crime_rate = max(0, min(self.crime_rate + random.uniform(-0.05, 0.05), 1)) self.economy = max(0.1, self.economy + random.uniform(-0.05, 0.05)) # Future expansion: simulate business growth, local events, etc. class Player: def __init__(self, world): self.world = world # Start in the middle of the screen self.x = SCREEN_WIDTH // 2 self.y = SCREEN_HEIGHT // 2 self.size = 20 self.speed = 4 self.wealth = 10000 # Starting money self.reputation = 50 # Scale from 0 to 100 self.current_city = None self.role = "Neutral" # Options: "Neutral", "Billionaire", "Mafia Boss" def handle_input(self): keys = pygame.key.get_pressed() if keys[pygame.K_LEFT] or keys[pygame.K_a]: self.x -= self.speed if keys[pygame.K_RIGHT] or keys[pygame.K_d]: self.x += self.speed if keys[pygame.K_UP] or keys[pygame.K_w]: self.y -= self.speed if keys[pygame.K_DOWN] or keys[pygame.K_s]: self.y += self.speed # Constrain player within screen boundaries self.x = max(0, min(self.x, SCREEN_WIDTH - self.size)) self.y = max(0, min(self.y, SCREEN_HEIGHT - self.size)) def draw(self, surface): pygame.draw.rect(surface, PLAYER_COLOR, (self.x, self.y, self.size, self.size)) def interact(self): """ Check if the player is near a city and return that city if so. """ for city in self.world.cities: dx = city.x - self.x dy = city.y - self.y dist = (dx**2 + dy**2) ** 0.5 if dist < city.radius + self.size: self.current_city = city return city self.current_city = None return None class Faction: def __init__(self, name, influence, funds): self.name = name self.influence = influence # 0 to 100 scale self.funds = funds def update_influence(self): # Factions fluctuate based on world events; simplistic update for now. self.influence = max(0, min(self.influence + random.uniform(-1, 1), 100)) class World: def __init__(self): self.cities = [] census_data = load_census_data("census.csv") for data in census_data: self.cities.append(City(data['name'], data['population'], data['x'], data['y'])) # Create factions representing divergent paths self.factions = { "Mafia": Faction("Underground Crime Syndicate", influence=50, funds=500000), "Corporation": Faction("Global Conglomerate", influence=50, funds=1000000) } self.day = 1 self.event_log = ["Welcome to Modern America!"] def simulate_day(self): # Update each city's simulation and each faction's influence. for city in self.cities: city.simulate_day() for faction in self.factions.values(): faction.update_influence() self.day += 1 self.event_log.append(f"Day {self.day}: Global events shift the balance.") # ------------------------------ # Game Class and Main Loop # ------------------------------ class Game: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Open World Sandbox: Modern America") self.clock = pygame.time.Clock() self.running = True self.world = World() self.player = Player(self.world) self.last_day_update = time.time() self.font = pygame.font.SysFont("arial", 18) # Menu system variables for contextual actions self.menu_mode = False self.menu_text = "" self.menu_options = {} def draw_ui(self): # Display player's stats and global state at the top left. stats = [ f"Wealth: ${self.player.wealth}", f"Reputation: {self.player.reputation}", f"Day: {self.world.day}", f"Role: {self.player.role}" ] y = 10 for stat in stats: text = self.font.render(stat, True, BLACK) self.screen.blit(text, (10, y)) y += 20 # Display the last few events y_offset = 100 for event in self.world.event_log[-3:]: event_text = self.font.render(event, True, BLACK) self.screen.blit(event_text, (10, y_offset)) y_offset += 20 if self.menu_mode: # Draw semi-transparent overlay for the menu overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)) overlay.set_alpha(200) overlay.fill(GREY) self.screen.blit(overlay, (0, 0)) lines = self.menu_text.split('\n') y = SCREEN_HEIGHT // 2 - len(lines)*15 for line in lines: menu_line = self.font.render(line, True, MENU_TEXT_COLOR) self.screen.blit(menu_line, (SCREEN_WIDTH//2 - 200, y)) y += 30 def process_menu_input(self, event): # Basic menu input processing: choose an option based on number keys. if event.type == pygame.KEYDOWN: if event.key == pygame.K_1 and "1" in self.menu_options: self.menu_options["1"]() elif event.key == pygame.K_2 and "2" in self.menu_options: self.menu_options["2"]() elif event.key == pygame.K_3 and "3" in self.menu_options: self.menu_options["3"]() elif event.key == pygame.K_ESCAPE: self.menu_mode = False # ------------------------------ # Player Career Choices # ------------------------------ def choose_billionaire_path(self): self.player.role = "Billionaire" self.player.wealth += 1000000 self.player.reputation += 10 self.world.factions["Corporation"].funds += 500000 self.world.event_log.append("Your investments soared! Welcome to the billionaire club.") self.menu_mode = False def choose_mafia_path(self): self.player.role = "Mafia Boss" self.player.wealth += 500000 self.player.reputation -= 20 # Underground life comes at a cost self.world.factions["Mafia"].funds += 250000 self.world.event_log.append("You now run an underground crime syndicate.") self.menu_mode = False def invest_in_city(self, city): # A sample economic action where investing can yield gains or losses. investment = random.randint(1000, 10000) result = random.choice(["gain", "loss"]) if result == "gain": profit = int(investment * random.uniform(0.1, 0.5) * city.economy) self.player.wealth += profit self.world.event_log.append(f"Invested in {city.name}: +${profit}") else: loss = int(investment * random.uniform(0.1, 0.5)) self.player.wealth = max(0, self.player.wealth - loss) self.world.event_log.append(f"Invested in {city.name}: -${loss}") self.menu_mode = False # ------------------------------ # Game Loop Methods # ------------------------------ def update(self): # Update the world simulation: every 10 seconds equals a new day. current_time = time.time() if current_time - self.last_day_update > 10: self.world.simulate_day() self.last_day_update = current_time # Process player movement self.player.handle_input() city = self.player.interact() # If near a city, open a contextual menu for choices. if city and not self.menu_mode: self.menu_mode = True self.menu_text = ( f"You have arrived in {city.name}.\n" "Choose your action:\n" "1. Invest in local businesses (Billionaire path)\n" "2. Engage in underground operations (Mafia path)\n" "3. Explore the city further\n" "Press ESC to cancel." ) # Map keys to functions. Option 3 just cancels the menu. self.menu_options = { "1": self.choose_billionaire_path, "2": self.choose_mafia_path, "3": lambda: setattr(self, 'menu_mode', False) } def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False if self.menu_mode: self.process_menu_input(event) def draw(self): self.screen.fill(WHITE) # Draw cities on the world map for city in self.world.cities: city.draw(self.screen) # Draw the player self.player.draw(self.screen) # Draw the UI overlay self.draw_ui() pygame.display.flip() def run(self): while self.running: self.clock.tick(FPS) self.handle_events() self.update() self.draw() pygame.quit() sys.exit() # ------------------------------ # Entry Point # ------------------------------ if __name__ == '__main__': game = Game() game.run()
Editor is loading...
Leave a Comment