Nitpick around

This commit is contained in:
Nguyễn Gia Phong 2020-04-28 17:50:36 +07:00
parent bc8579329e
commit d3839f160e
7 changed files with 61 additions and 61 deletions

View File

@ -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``.

View File

@ -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

View File

@ -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).

View File

@ -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();
} }
} }
} }

View File

@ -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())

View File

@ -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

@ -1 +1 @@
Subproject commit 7375e5e6615dc11b9baccca059f258dbaf30f667 Subproject commit 1a6a95ddd66167356c94a984b2d31d8e1aff15ab