mirror of
https://github.com/GoodStartLabs/AI_Diplomacy.git
synced 2026-04-24 17:05:04 +00:00
WIP: Starting work on running games via websocket
First crack, mostly Claude, on running each agent as an individual connection to the server via WebSocket.
This commit is contained in:
parent
78d9ed6818
commit
aa0e5852e5
10 changed files with 2064 additions and 855 deletions
|
|
@ -6,13 +6,9 @@ and interacting with a Diplomacy server via WebSocket.
|
|||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from loguru import logger
|
||||
from websocket_diplomacy_client import connect_to_diplomacy_server
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def basic_client_example():
|
||||
"""
|
||||
|
|
@ -25,7 +21,7 @@ async def basic_client_example():
|
|||
hostname="localhost",
|
||||
port=8432,
|
||||
username="test_player",
|
||||
password="test_password"
|
||||
password="test_password",
|
||||
)
|
||||
logger.info("Connected successfully!")
|
||||
|
||||
|
|
@ -34,8 +30,10 @@ async def basic_client_example():
|
|||
games = await client.list_games()
|
||||
logger.info(f"Found {len(games)} games:")
|
||||
for game in games:
|
||||
logger.info(f" Game {game.get('game_id', 'unknown')}: {game.get('status', 'unknown')} "
|
||||
f"({game.get('n_players', 0)}/{game.get('n_controls', 0)} players)")
|
||||
logger.info(
|
||||
f" Game {game.get('game_id', 'unknown')}: {game.get('status', 'unknown')} "
|
||||
f"({game.get('n_players', 0)}/{game.get('n_controls', 0)} players)"
|
||||
)
|
||||
|
||||
# Get available maps
|
||||
logger.info("Getting available maps...")
|
||||
|
|
@ -49,7 +47,7 @@ async def basic_client_example():
|
|||
rules=["NO_PRESS", "IGNORE_ERRORS", "POWER_CHOICE"],
|
||||
power_name="FRANCE", # Control France
|
||||
n_controls=1, # Only need 1 player to start (for testing)
|
||||
deadline=None # No time pressure
|
||||
deadline=None, # No time pressure
|
||||
)
|
||||
logger.info(f"Created game {client.game_id} as {client.power_name}")
|
||||
|
||||
|
|
@ -62,21 +60,21 @@ async def basic_client_example():
|
|||
# Get possible orders
|
||||
logger.info("Getting possible orders for France...")
|
||||
possible_orders = client.get_all_possible_orders()
|
||||
france_orders = possible_orders.get('FRANCE', [])
|
||||
france_orders = possible_orders.get("FRANCE", [])
|
||||
logger.info(f"France can make {len(france_orders)} possible orders")
|
||||
if france_orders:
|
||||
logger.info(f"First few orders: {france_orders[:5]}")
|
||||
|
||||
# Submit some orders (example: hold all units)
|
||||
logger.info("Submitting hold orders for all French units...")
|
||||
units = client.get_units('FRANCE')
|
||||
units = client.get_units("FRANCE")
|
||||
hold_orders = []
|
||||
for unit in units:
|
||||
# Format: "A PAR H" means Army in Paris holds
|
||||
hold_orders.append(f"{unit} H")
|
||||
|
||||
|
||||
if hold_orders:
|
||||
await client.set_orders('FRANCE', hold_orders)
|
||||
await client.set_orders("FRANCE", hold_orders)
|
||||
logger.info(f"Submitted orders: {hold_orders}")
|
||||
|
||||
# Try to process the game (might fail if we don't have admin rights)
|
||||
|
|
@ -84,11 +82,13 @@ async def basic_client_example():
|
|||
try:
|
||||
await client.process_game()
|
||||
logger.info("Game processed successfully")
|
||||
|
||||
|
||||
# Synchronize to get updated state
|
||||
await client.synchronize()
|
||||
logger.info(f"After processing - Current phase: {client.get_current_phase()}")
|
||||
|
||||
logger.info(
|
||||
f"After processing - Current phase: {client.get_current_phase()}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not process game (normal if not admin): {e}")
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ async def basic_client_example():
|
|||
logger.error(f"Error in example: {e}", exc_info=True)
|
||||
finally:
|
||||
# Clean up
|
||||
if 'client' in locals():
|
||||
if "client" in locals():
|
||||
await client.close()
|
||||
logger.info("Example completed")
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ async def basic_client_example():
|
|||
async def join_existing_game_example(game_id: str):
|
||||
"""
|
||||
Example showing how to join an existing game.
|
||||
|
||||
|
||||
Args:
|
||||
game_id: ID of the game to join
|
||||
"""
|
||||
|
|
@ -119,7 +119,7 @@ async def join_existing_game_example(game_id: str):
|
|||
hostname="localhost",
|
||||
port=8432,
|
||||
username="test_player_2",
|
||||
password="test_password"
|
||||
password="test_password",
|
||||
)
|
||||
|
||||
# Join as an observer first
|
||||
|
|
@ -133,13 +133,15 @@ async def join_existing_game_example(game_id: str):
|
|||
|
||||
# List powers and their status
|
||||
for power_name, power in client.powers.items():
|
||||
logger.info(f"{power_name}: {len(power.centers)} centers, "
|
||||
f"{len(power.units)} units, eliminated: {power.is_eliminated()}")
|
||||
logger.info(
|
||||
f"{power_name}: {len(power.centers)} centers, "
|
||||
f"{len(power.units)} units, eliminated: {power.is_eliminated()}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error joining game: {e}", exc_info=True)
|
||||
finally:
|
||||
if 'client' in locals():
|
||||
if "client" in locals():
|
||||
await client.close()
|
||||
|
||||
|
||||
|
|
@ -149,28 +151,31 @@ async def message_sending_example():
|
|||
"""
|
||||
try:
|
||||
client = await connect_to_diplomacy_server()
|
||||
|
||||
|
||||
# Create a game with PRESS allowed
|
||||
game = await client.create_game(
|
||||
rules=["IGNORE_ERRORS", "POWER_CHOICE"], # Remove NO_PRESS to allow messages
|
||||
rules=[
|
||||
"IGNORE_ERRORS",
|
||||
"POWER_CHOICE",
|
||||
], # Remove NO_PRESS to allow messages
|
||||
power_name="FRANCE",
|
||||
n_controls=1
|
||||
n_controls=1,
|
||||
)
|
||||
|
||||
|
||||
# Send a public message
|
||||
await client.send_message(
|
||||
sender="FRANCE",
|
||||
recipient="GLOBAL",
|
||||
message="Greetings from France! Let's have a fair game."
|
||||
message="Greetings from France! Let's have a fair game.",
|
||||
)
|
||||
logger.info("Sent public message")
|
||||
|
||||
|
||||
# Send a private message (would need another power to be present)
|
||||
try:
|
||||
await client.send_message(
|
||||
sender="FRANCE",
|
||||
recipient="ENGLAND",
|
||||
message="Hello England, shall we discuss an alliance?"
|
||||
message="Hello England, shall we discuss an alliance?",
|
||||
)
|
||||
logger.info("Sent private message to England")
|
||||
except Exception as e:
|
||||
|
|
@ -179,17 +184,18 @@ async def message_sending_example():
|
|||
except Exception as e:
|
||||
logger.error(f"Error in messaging example: {e}", exc_info=True)
|
||||
finally:
|
||||
if 'client' in locals():
|
||||
if "client" in locals():
|
||||
await client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
# Join existing game if game ID provided as argument
|
||||
game_id = sys.argv[1]
|
||||
asyncio.run(join_existing_game_example(game_id))
|
||||
else:
|
||||
# Run basic example
|
||||
asyncio.run(basic_client_example())
|
||||
asyncio.run(basic_client_example())
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue