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