Nitpick around
This commit is contained in:
parent
bc8579329e
commit
d3839f160e
|
@ -27,11 +27,11 @@ Brutal Maze has a few notable features:
|
||||||
Installation
|
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:
|
The installation procedure should be as simple as follows:
|
||||||
|
|
||||||
* Install Python and `pip <https://pip.pypa.io/en/latest/>`_. Make sure the
|
* 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``.
|
is in your ``$PATH``.
|
||||||
* Open Terminal or Command Prompt and run ``pip install --user brutalmaze``.
|
* Open Terminal or Command Prompt and run ``pip install --user brutalmaze``.
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with Brutal Maze. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
__version__ = '0.9.1'
|
__version__ = '0.9.2'
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from argparse import ArgumentParser, FileType, RawTextHelpFormatter
|
from argparse import ArgumentParser, FileType, RawTextHelpFormatter
|
||||||
|
@ -32,7 +32,7 @@ from threading import Thread
|
||||||
with redirect_stdout(StringIO()): import pygame
|
with redirect_stdout(StringIO()): import pygame
|
||||||
from pygame import KEYDOWN, MOUSEBUTTONUP, QUIT, VIDEORESIZE
|
from pygame import KEYDOWN, MOUSEBUTTONUP, QUIT, VIDEORESIZE
|
||||||
from pygame.time import Clock, get_ticks
|
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 appdirs import AppDirs
|
||||||
|
|
||||||
from .constants import SETTINGS, ICON, SFX, SFX_NOISE, HERO_SPEED, MIDDLE
|
from .constants import SETTINGS, ICON, SFX, SFX_NOISE, HERO_SPEED, MIDDLE
|
||||||
|
|
|
@ -37,7 +37,7 @@ Frequency: 30
|
||||||
# Enabling remote control will disable control via keyboard and mouse.
|
# Enabling remote control will disable control via keyboard and mouse.
|
||||||
Enable: no
|
Enable: no
|
||||||
Host: localhost
|
Host: localhost
|
||||||
Port: 8089
|
Port: 42069
|
||||||
# Timeout on blocking socket operations, in seconds.
|
# Timeout on blocking socket operations, in seconds.
|
||||||
Timeout: 1.0
|
Timeout: 1.0
|
||||||
# Disable graphics and sound (only if socket server is enabled).
|
# Disable graphics and sound (only if socket server is enabled).
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace BrutalmazeClient
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
const string host = "localhost";
|
const string host = "localhost";
|
||||||
const int port = 8089;
|
const int port = 42069;
|
||||||
Socket client_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
Socket client_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||||
client_socket.Connect(host, port);
|
client_socket.Connect(host, port);
|
||||||
Random rnd = new Random();
|
Random rnd = new Random();
|
||||||
|
@ -101,4 +101,4 @@ namespace BrutalmazeClient
|
||||||
client_socket.Close();
|
client_socket.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
from contextlib import closing, suppress
|
||||||
from math import inf, atan2, degrees
|
from math import inf, atan2, degrees
|
||||||
from random import randrange
|
from random import randrange, shuffle
|
||||||
from socket import socket
|
from socket import socket
|
||||||
|
|
||||||
AROUND = [5, 2, 1, 0, 3, 6, 7, 8]
|
AROUND = [5, 2, 1, 0, 3, 6, 7, 8]
|
||||||
|
@ -18,56 +19,54 @@ def is_wall(maze, y, x):
|
||||||
return maze[y][x] != '0'
|
return maze[y][x] != '0'
|
||||||
|
|
||||||
|
|
||||||
clientsocket = socket()
|
def get_move(maze, move):
|
||||||
clientsocket.connect(('localhost', 8089))
|
"""Return an outstanding move."""
|
||||||
corners, sides = [0, 2, 6, 8], [1, 3, 5, 7]
|
moves, around = get_moves(len(maze) // 2, len(maze[0]) // 2), AROUND[:]
|
||||||
around, move = [0, 1, 2, 3, 5, 6, 7, 8], 4
|
if move != 4 and not is_wall(maze, *moves[move]): return move
|
||||||
while True:
|
if move == 4:
|
||||||
length = clientsocket.recv(7).decode()
|
shuffle(around)
|
||||||
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
|
|
||||||
else:
|
else:
|
||||||
attack = 1
|
idx = AROUND.index(move)
|
||||||
clientsocket.send('{} {} {}'.format(move, angle, attack).encode())
|
around.sort(key=lambda i: abs(abs(abs(AROUND.index(i)-idx)-4)-4))
|
||||||
clientsocket.close()
|
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())
|
||||||
|
|
|
@ -21,6 +21,7 @@ classifiers = [
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 3 :: Only',
|
'Programming Language :: Python :: 3 :: Only',
|
||||||
'Topic :: Games/Entertainment :: Arcade']
|
'Topic :: Games/Entertainment :: Arcade']
|
||||||
|
requires-python = '>=3.6'
|
||||||
keywords = 'pygame,shmup,maze,ai-challenges'
|
keywords = 'pygame,shmup,maze,ai-challenges'
|
||||||
license = 'AGPLv3+'
|
license = 'AGPLv3+'
|
||||||
|
|
||||||
|
|
2
wiki
2
wiki
|
@ -1 +1 @@
|
||||||
Subproject commit 7375e5e6615dc11b9baccca059f258dbaf30f667
|
Subproject commit 1a6a95ddd66167356c94a984b2d31d8e1aff15ab
|
Loading…
Reference in New Issue