#!/usr/bin/env python3 """Simple IRC bot that plays monop by sending dot-prefixed commands.""" import ssl import sys import time import random import irc.client import irc.connection SERVER = "irc.darkscience.net" PORT = 6697 CHANNEL = "#monop-dev" class PlayerBot: def __init__(self, nick, commands): self.nick = nick self.commands = list(commands) # list of (delay, command) tuples self.cmd_idx = 0 self.connection = None self.joined = False self.last_cmd_time = 0 def on_connect(self, conn, event): print(f"[{self.nick}] Connected, joining {CHANNEL}", flush=True) self.connection = conn conn.join(CHANNEL) def on_join(self, conn, event): if event.source.nick == self.nick: print(f"[{self.nick}] Joined {CHANNEL}", flush=True) self.joined = True self.last_cmd_time = time.time() def on_pubmsg(self, conn, event): msg = event.arguments[0] if event.arguments else "" nick = event.source.nick if event.source else "" # React to game prompts if nick == "monopoly" and self.joined: if "Do you want to buy?" in msg: time.sleep(0.5) conn.privmsg(CHANNEL, ".yes") elif "How many players?" in msg: time.sleep(0.5) conn.privmsg(CHANNEL, ".3") def send_next_command(self): if self.cmd_idx < len(self.commands) and self.joined: delay, cmd = self.commands[self.cmd_idx] if time.time() - self.last_cmd_time >= delay: print(f"[{self.nick}] Sending: {cmd}", flush=True) self.connection.privmsg(CHANNEL, cmd) self.last_cmd_time = time.time() self.cmd_idx += 1 return True return False def main(): # Script the game setup and several turns # Player 1 starts the game with ".3" (3 players) # Then each player provides their name # Then they take turns rolling (just press enter = ".roll" or ".") alice_cmds = [ (3, ".3"), # start 3 player game (2, ".Alice"), # enter name (8, "."), # roll (first turn after setup) (4, "."), # action/roll (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), ] bob_cmds = [ (6, ".Bob"), # enter name (10, "."), # roll (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), ] charlie_cmds = [ (8, ".Charlie"), # enter name (12, "."), # roll (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), (6, "."), ] bots = [ PlayerBot("alice_m", alice_cmds), PlayerBot("bob_m", bob_cmds), PlayerBot("charlie_m", charlie_cmds), ] reactor = irc.client.Reactor() ssl_ctx = ssl.create_default_context() for bot in bots: factory = irc.connection.Factory( wrapper=lambda s: ssl_ctx.wrap_socket(s, server_hostname=SERVER)) server = reactor.server() server.connect(SERVER, PORT, bot.nick, connect_factory=factory) server.add_global_handler("welcome", bot.on_connect) server.add_global_handler("join", bot.on_join) server.add_global_handler("pubmsg", bot.on_pubmsg) time.sleep(1) # stagger connections print("All bots connecting...", flush=True) start = time.time() timeout = 180 # 3 minutes while time.time() - start < timeout: reactor.process_once(timeout=0.5) for bot in bots: bot.send_next_command() # Check if all bots are done if all(b.cmd_idx >= len(b.commands) for b in bots): print("All commands sent. Waiting 10s for final output...", flush=True) end = time.time() + 10 while time.time() < end: reactor.process_once(timeout=0.5) break print("Done!", flush=True) for bot in bots: if bot.connection: bot.connection.quit("Game over!") if __name__ == "__main__": main()