diff --git a/README.rst b/README.rst
index 33a0ff0..7203aaa 100644
--- a/README.rst
+++ b/README.rst
@@ -27,11 +27,11 @@ Brutal Maze has a few notable features:
Installation
------------
-Brutal Maze is written in Python and is compatible with both version 2 and 3.
+Brutal Maze is written in Python and is compatible version 3.6 and above.
The installation procedure should be as simple as follows:
* Install Python and `pip `_. Make sure the
- directory for `Python scripts `_
+ directory for `Python scripts `_
is in your ``$PATH``.
* Open Terminal or Command Prompt and run ``pip install --user brutalmaze``.
diff --git a/brutalmaze/game.py b/brutalmaze/game.py
index d30c44d..fef7494 100644
--- a/brutalmaze/game.py
+++ b/brutalmaze/game.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with Brutal Maze. If not, see .
-__version__ = '0.9.1'
+__version__ = '0.9.2'
import re
from argparse import ArgumentParser, FileType, RawTextHelpFormatter
@@ -32,7 +32,7 @@ from threading import Thread
with redirect_stdout(StringIO()): import pygame
from pygame import KEYDOWN, MOUSEBUTTONUP, QUIT, VIDEORESIZE
from pygame.time import Clock, get_ticks
-from palace import free, use_context, Device, Context, Buffer
+from palace import free, use_context, Device, Context
from appdirs import AppDirs
from .constants import SETTINGS, ICON, SFX, SFX_NOISE, HERO_SPEED, MIDDLE
diff --git a/brutalmaze/settings.ini b/brutalmaze/settings.ini
index d78aed2..5f4b4cd 100644
--- a/brutalmaze/settings.ini
+++ b/brutalmaze/settings.ini
@@ -37,7 +37,7 @@ Frequency: 30
# Enabling remote control will disable control via keyboard and mouse.
Enable: no
Host: localhost
-Port: 8089
+Port: 42069
# Timeout on blocking socket operations, in seconds.
Timeout: 1.0
# Disable graphics and sound (only if socket server is enabled).
diff --git a/client-examples/BrutalmazeClient.cs b/client-examples/BrutalmazeClient.cs
index 0d87bd3..cd3edfd 100644
--- a/client-examples/BrutalmazeClient.cs
+++ b/client-examples/BrutalmazeClient.cs
@@ -9,7 +9,7 @@ namespace BrutalmazeClient
static void Main(string[] args)
{
const string host = "localhost";
- const int port = 8089;
+ const int port = 42069;
Socket client_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
client_socket.Connect(host, port);
Random rnd = new Random();
@@ -101,4 +101,4 @@ namespace BrutalmazeClient
client_socket.Close();
}
}
-}
\ No newline at end of file
+}
diff --git a/client-examples/hit-and-run.py b/client-examples/hit-and-run.py
index ef90276..7959315 100755
--- a/client-examples/hit-and-run.py
+++ b/client-examples/hit-and-run.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
+from contextlib import closing, suppress
from math import inf, atan2, degrees
-from random import randrange
+from random import randrange, shuffle
from socket import socket
AROUND = [5, 2, 1, 0, 3, 6, 7, 8]
@@ -18,56 +19,54 @@ def is_wall(maze, y, x):
return maze[y][x] != '0'
-clientsocket = socket()
-clientsocket.connect(('localhost', 8089))
-corners, sides = [0, 2, 6, 8], [1, 3, 5, 7]
-around, move = [0, 1, 2, 3, 5, 6, 7, 8], 4
-while True:
- length = clientsocket.recv(7).decode()
- if length in ('', '0000000'): break # connection closed or game over
- data = iter(clientsocket.recv(int(length)).decode().split())
- nh, ne, nb, score = (int(next(data)) for _ in range(4))
- maze = [list(next(data)) for _ in range(nh)]
- hp = (lambda c: 0 if c == 48 else 123 - c)(ord(next(data)))
- hx, hy, ha = (int(next(data)) for _ in range(3))
- attackable, heal = (bool(int(next(data))) for _ in range(2))
-
- if nh:
- moves = get_moves(len(maze) // 2, len(maze[0]) // 2)
- if move == 4 or is_wall(maze, *moves[move]):
- try:
- idx = AROUND.index(move)
- except ValueError:
- pass
- else:
- around.sort(key=(lambda i: (lambda x: min(x, 8 - x))(
- abs(AROUND.index(i) - idx))))
- for move in around:
- idx = AROUND.index(move)
- if all(map(
- (lambda i: not is_wall(maze, *moves[i])),
- (move, AROUND[idx - 1], AROUND[idx - 7]))):
- break
- else:
- move = 4
-
- angle, shortest = ha, inf
- for _ in range(ne):
- p = 3 - (ord(next(data)) - 97)%3
- x, y, a = (int(next(data)) for _ in range(3))
- d = ((x - hx)**2 + (y - hy)**2)**0.5
- if d < shortest:
- shortest = d
- b = degrees(atan2(y - hy, x - hx))
- angle = round(b + 360 if b < 0 else b)
-
- if hp <= 2 and heal:
- move, attack = 4, 2
- elif not ne:
- attack = randrange(3) * (attackable and hp > 2)
- elif shortest < 160:
- move, angle, attack = AROUND[round(angle/45 - 0.5) - 4], ha, 2
+def get_move(maze, move):
+ """Return an outstanding move."""
+ moves, around = get_moves(len(maze) // 2, len(maze[0]) // 2), AROUND[:]
+ if move != 4 and not is_wall(maze, *moves[move]): return move
+ if move == 4:
+ shuffle(around)
else:
- attack = 1
- clientsocket.send('{} {} {}'.format(move, angle, attack).encode())
-clientsocket.close()
+ idx = AROUND.index(move)
+ around.sort(key=lambda i: abs(abs(abs(AROUND.index(i)-idx)-4)-4))
+ for move in around:
+ idx = AROUND.index(move)
+ if all(not is_wall(maze, *moves[i])
+ for i in (move, AROUND[idx - 1], AROUND[idx - 7])):
+ return move
+ return 4
+
+
+with suppress(KeyboardInterrupt), closing(socket()) as sock:
+ sock.connect(('localhost', 42069))
+ move = 4
+ while True:
+ length = sock.recv(7).decode()
+ # connection closed or game over
+ if length in ('', '0000000'): break
+ data = iter(sock.recv(int(length)).decode().split())
+ nh, ne, nb, score = (int(next(data)) for i in range(4))
+ maze = [list(next(data)) for i in range(nh)]
+ hp = (lambda c: 0 if c == 48 else 123 - c)(ord(next(data)))
+ hx, hy, ha = (int(next(data)) for i in range(3))
+ attackable, heal = (bool(int(next(data))) for i in range(2))
+
+ if nh: move = get_move(maze, move)
+ angle, shortest = ha, inf
+ for i in range(ne):
+ p = 3 - (ord(next(data)) - 97)%3
+ x, y, a = (int(next(data)) for j in range(3))
+ d = ((x - hx)**2 + (y - hy)**2)**0.5
+ if d < shortest:
+ shortest = d
+ b = degrees(atan2(y - hy, x - hx))
+ angle = round(b + 360 if b < 0 else b)
+
+ if hp <= 2 and heal:
+ move, attack = 4, 2
+ elif not ne:
+ attack = randrange(3) * (attackable and hp > 2)
+ elif shortest < 160:
+ move, angle, attack = AROUND[round(angle/45 - 0.5) - 4], ha, 2
+ else:
+ attack = 1
+ sock.send(f'{move} {angle} {attack}'.encode())
diff --git a/pyproject.toml b/pyproject.toml
index 8cbcad4..f56787d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -21,6 +21,7 @@ classifiers = [
'Programming Language :: Python',
'Programming Language :: Python :: 3 :: Only',
'Topic :: Games/Entertainment :: Arcade']
+requires-python = '>=3.6'
keywords = 'pygame,shmup,maze,ai-challenges'
license = 'AGPLv3+'
diff --git a/wiki b/wiki
index 7375e5e..1a6a95d 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit 7375e5e6615dc11b9baccca059f258dbaf30f667
+Subproject commit 1a6a95ddd66167356c94a984b2d31d8e1aff15ab