Implement stuck snake mechanics, persistent colors, and length display

Major gameplay changes:
- Snakes no longer die from collisions
- When blocked, snakes get "stuck" - head stays in place, tail shrinks by 1 per tick
- Snakes auto-unstick when obstacle clears (other snakes move/shrink away)
- Minimum snake length is 1 (head-only)
- Game runs continuously without rounds or game-over state

Color system:
- Each player gets a persistent color for their entire connection
- Colors assigned on join, rotate through available colors
- Color follows player even after disconnect/reconnect
- Works for both desktop and web clients

Display improvements:
- Show snake length instead of score
- Length accurately reflects current snake size
- Updates in real-time as snakes grow/shrink

Server fixes:
- Fixed HTTP server initialization issues
- Changed default host to 0.0.0.0 for network multiplayer
- Improved file serving with proper routing

Testing:
- Updated all collision tests for stuck mechanics
- Added tests for stuck/unstick behavior
- Added tests for color persistence
- All 12 tests passing

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Vladyslav Doloman
2025-10-04 16:39:30 +03:00
parent ec8e9cd5fb
commit 84a58038f7
10 changed files with 271 additions and 133 deletions

View File

@@ -75,13 +75,14 @@ async def main() -> None:
)
# Start HTTP server if enabled
http_task = None
http_server = None
if not args.no_http and args.http_port > 0:
web_dir = Path(args.web_dir)
if web_dir.exists():
http_server = HTTPServer(web_dir, args.http_port, "0.0.0.0")
# Use same host as game server for HTTP
http_host = args.host if args.host != "0.0.0.0" else "localhost"
http_server = HTTPServer(web_dir, args.http_port, http_host)
await http_server.start()
http_task = asyncio.create_task(asyncio.Future()) # Keep running
else:
print(f"Warning: Web directory '{web_dir}' not found. HTTP server disabled.")
@@ -89,8 +90,8 @@ async def main() -> None:
try:
await server.start()
finally:
if http_task:
http_task.cancel()
if http_server:
await http_server.stop()
if __name__ == "__main__":