Files
claudePySnake/run_server.py
Vladyslav Doloman ce492b0dc2 Add input buffering, auto-start, and gameplay improvements
Input buffer system:
- Added 3-slot direction input buffer to handle rapid key presses
- Buffer ignores duplicate inputs (same key pressed multiple times)
- Opposite direction replaces last buffered input (e.g., LEFT→RIGHT replaces LEFT)
- Buffer overflow replaces last slot when full
- Multi-segment snakes skip invalid 180° turns when consuming buffer
- Head-only snakes (length=1) can turn 180° for flexibility

Gameplay improvements:
- Desktop client auto-starts game on connect (no SPACE needed)
- Field populates with 3 apples when no players connected
- HTTP server now binds to 0.0.0.0 for network access (matches game server)

Testing:
- Added 7 new tests for input buffer functionality
- Added test for zero-player apple spawning
- All 19 tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-04 19:11:20 +03:00

98 lines
2.7 KiB
Python

"""Run the Snake game server."""
import asyncio
import argparse
from pathlib import Path
from src.server.game_server import GameServer
from src.server.http_server import HTTPServer
from src.shared.constants import DEFAULT_HOST, DEFAULT_PORT, DEFAULT_WS_PORT, DEFAULT_HTTP_PORT
async def main() -> None:
"""Run the server with command line arguments."""
parser = argparse.ArgumentParser(description="Run the Snake game server")
parser.add_argument(
"--host",
default=DEFAULT_HOST,
help=f"Host address to bind to (default: {DEFAULT_HOST})",
)
parser.add_argument(
"--port",
type=int,
default=DEFAULT_PORT,
help=f"TCP port number (default: {DEFAULT_PORT})",
)
parser.add_argument(
"--ws-port",
type=int,
default=DEFAULT_WS_PORT,
help=f"WebSocket port (default: {DEFAULT_WS_PORT}, 0 to disable)",
)
parser.add_argument(
"--http-port",
type=int,
default=DEFAULT_HTTP_PORT,
help=f"HTTP server port (default: {DEFAULT_HTTP_PORT}, 0 to disable)",
)
parser.add_argument(
"--web-dir",
default="web",
help="Directory containing web client files (default: web)",
)
parser.add_argument(
"--name",
default="Snake Server",
help="Server name for discovery (default: Snake Server)",
)
parser.add_argument(
"--no-discovery",
action="store_true",
help="Disable multicast discovery beacon",
)
parser.add_argument(
"--no-websocket",
action="store_true",
help="Disable WebSocket server",
)
parser.add_argument(
"--no-http",
action="store_true",
help="Disable HTTP server (for production with external web server)",
)
args = parser.parse_args()
# Determine WebSocket port
ws_port = None if args.no_websocket or args.ws_port == 0 else args.ws_port
# Create game server
server = GameServer(
host=args.host,
port=args.port,
server_name=args.name,
enable_discovery=not args.no_discovery,
ws_port=ws_port,
)
# Start HTTP server if enabled
http_server = None
if not args.no_http and args.http_port > 0:
web_dir = Path(args.web_dir)
if web_dir.exists():
# Use same host as game server for HTTP
http_server = HTTPServer(web_dir, args.http_port, args.host)
await http_server.start()
else:
print(f"Warning: Web directory '{web_dir}' not found. HTTP server disabled.")
# Start game server
try:
await server.start()
finally:
if http_server:
await http_server.stop()
if __name__ == "__main__":
asyncio.run(main())