about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--README.rst4
-rw-r--r--brutalmaze/game.py4
-rw-r--r--brutalmaze/settings.ini2
-rw-r--r--client-examples/BrutalmazeClient.cs4
-rwxr-xr-xclient-examples/hit-and-run.py101
-rw-r--r--pyproject.toml1
m---------wiki0
7 files changed, 58 insertions, 58 deletions
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 <https://pip.pypa.io/en/latest/>`_. Make sure the
-  directory for `Python scripts <https://docs.python.org/2/install/index.html#alternate-installation-the-user-scheme>`_
+  directory for `Python scripts <https://docs.python.org/3/install/index.html#alternate-installation-the-user-scheme>`_
   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 <https://www.gnu.org/licenses/>.
 
-__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))
+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:
+        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
 
-    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)
+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 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
-    clientsocket.send('{} {} {}'.format(move, angle, attack).encode())
-clientsocket.close()
+        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
-Subproject 7375e5e6615dc11b9baccca059f258dbaf30f66
+Subproject 1a6a95ddd66167356c94a984b2d31d8e1aff15a