Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
b6bef1a78e
@ -1,23 +1,33 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from .coordinate import Coordinate, DistanceAlgorithm
|
from .coordinate import Coordinate, DistanceAlgorithm
|
||||||
|
from .types import Numeric
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from heapq import heappop, heappush
|
from heapq import heappop, heappush
|
||||||
from typing import Any, Dict, List, Union
|
from typing import Any, Dict, List, Union
|
||||||
|
|
||||||
OFF = False
|
OFF = False
|
||||||
ON = True
|
ON = True
|
||||||
Numeric = Union[int, float]
|
|
||||||
|
|
||||||
|
|
||||||
class GridTransformation(Enum):
|
class GridTransformation(Enum):
|
||||||
FLIP_X = 1
|
# Rotations always take the axis to rotate around as if it were the z-axis and then rotate clockwise
|
||||||
FLIP_HORIZONTALLY = 1 # alias for FLIP_X; prep for 3d-transformations
|
# Counter-Rotations likewise, just anti-clockwise
|
||||||
FLIP_VERTICALLY = 2
|
# 3D-only OPs have a number > 10
|
||||||
FLIP_DIAGONALLY = 3
|
ROTATE_Z = 3
|
||||||
FLIP_DIAGONALLY_REV = 4
|
ROTATE_X = 11
|
||||||
ROTATE_RIGHT = 5
|
ROTATE_Y = 12
|
||||||
ROTATE_LEFT = 6
|
COUNTER_ROTATE_X = 14
|
||||||
ROTATE_TWICE = 7
|
COUNTER_ROTATE_Y = 15
|
||||||
|
COUNTER_ROTATE_Z = 7
|
||||||
|
FLIP_X = 4
|
||||||
|
FLIP_Y = 5
|
||||||
|
FLIP_Z = 13
|
||||||
|
|
||||||
|
# Handy aliases
|
||||||
|
FLIP_HORIZONTALLY = 5
|
||||||
|
FLIP_VERTICALLY = 4
|
||||||
|
ROTATE_RIGHT = 3
|
||||||
|
ROTATE_LEFT = 7
|
||||||
|
|
||||||
|
|
||||||
class Grid:
|
class Grid:
|
||||||
@ -162,40 +172,40 @@ class Grid:
|
|||||||
self.set(c2, buf)
|
self.set(c2, buf)
|
||||||
|
|
||||||
def transform(self, mode: GridTransformation):
|
def transform(self, mode: GridTransformation):
|
||||||
if self.mode3D:
|
if mode.value > 10 and not self.mode3D:
|
||||||
raise NotImplementedError() # that will take some time and thought
|
raise ValueError("Operation not possible in 2D space", mode)
|
||||||
|
|
||||||
if mode == GridTransformation.FLIP_HORIZONTALLY:
|
coords = self.__grid
|
||||||
for x in range(self.minX, (self.maxX - self.minX) // 2 + 1):
|
self.__grid, self.minX, self.maxX, self.minY, self.maxY, self.minZ, self.maxZ = {}, 0, 0, 0, 0, 0, 0
|
||||||
for y in range(self.minY, self.maxY + 1):
|
if mode == GridTransformation.ROTATE_X:
|
||||||
self.flip(Coordinate(x, y), Coordinate(self.maxX - x, y))
|
for c, v in coords.items():
|
||||||
elif mode == GridTransformation.FLIP_VERTICALLY:
|
self.set(Coordinate(c.x, -c.z, c.y), v)
|
||||||
for y in range(self.minY, (self.maxY - self.minY) // 2 + 1):
|
elif mode == GridTransformation.ROTATE_Y:
|
||||||
for x in range(self.minX, self.maxX + 1):
|
for c, v in coords.items():
|
||||||
self.flip(Coordinate(x, y), Coordinate(x, self.maxY - y))
|
self.set(Coordinate(-c.z, c.y, c.x), v)
|
||||||
elif mode == GridTransformation.FLIP_DIAGONALLY:
|
elif mode == GridTransformation.ROTATE_Z:
|
||||||
self.transform(GridTransformation.ROTATE_LEFT)
|
for c, v in coords.items():
|
||||||
self.transform(GridTransformation.FLIP_HORIZONTALLY)
|
self.set(Coordinate(c.y, -c.x, c.z), v)
|
||||||
elif mode == GridTransformation.FLIP_DIAGONALLY_REV:
|
elif mode == GridTransformation.COUNTER_ROTATE_X:
|
||||||
self.transform(GridTransformation.ROTATE_RIGHT)
|
for c, v in coords.items():
|
||||||
self.transform(GridTransformation.FLIP_HORIZONTALLY)
|
self.set(Coordinate(c.x, c.z, -c.y), v)
|
||||||
elif mode == GridTransformation.ROTATE_LEFT:
|
elif mode == GridTransformation.COUNTER_ROTATE_Y:
|
||||||
newGrid = Grid()
|
for c, v in coords.items():
|
||||||
for x in range(self.maxX, self.minX - 1, -1):
|
self.set(Coordinate(c.z, c.y, -c.x), v)
|
||||||
for y in range(self.minY, self.maxY + 1):
|
elif mode == GridTransformation.COUNTER_ROTATE_Z:
|
||||||
newGrid.set(Coordinate(y, self.maxX - x), self.get(Coordinate(x, y)))
|
for c, v in coords.items():
|
||||||
|
self.set(Coordinate(-c.y, c.x, c.z), v)
|
||||||
self.__dict__.update(newGrid.__dict__)
|
elif mode == GridTransformation.FLIP_X:
|
||||||
elif mode == GridTransformation.ROTATE_RIGHT:
|
for c, v in coords.items():
|
||||||
newGrid = Grid()
|
self.set(Coordinate(-c.x, c.y, c.z), v)
|
||||||
for x in range(self.minX, self.maxX + 1):
|
elif mode == GridTransformation.FLIP_Y:
|
||||||
for y in range(self.maxY, self.minY - 1, -1):
|
for c, v in coords.items():
|
||||||
newGrid.set(Coordinate(self.maxY - y, x), self.get(Coordinate(x, y)))
|
self.set(Coordinate(c.x, -c.y, c.z), v)
|
||||||
|
elif mode == GridTransformation.FLIP_Z:
|
||||||
self.__dict__.update(newGrid.__dict__)
|
for c, v in coords.items():
|
||||||
elif mode == GridTransformation.ROTATE_TWICE:
|
self.set(Coordinate(c.x, c.y, -c.z), v)
|
||||||
self.transform(GridTransformation.ROTATE_RIGHT)
|
else:
|
||||||
self.transform(GridTransformation.ROTATE_RIGHT)
|
raise NotImplementedError(mode)
|
||||||
|
|
||||||
def getPath(self, pos_from: Coordinate, pos_to: Coordinate, includeDiagonal: bool, walls: List[Any] = None,
|
def getPath(self, pos_from: Coordinate, pos_to: Coordinate, includeDiagonal: bool, walls: List[Any] = None,
|
||||||
weighted: bool = False) -> Union[None, List[Coordinate]]:
|
weighted: bool = False) -> Union[None, List[Coordinate]]:
|
||||||
|
|||||||
44
tools/irc.py
44
tools/irc.py
@ -1,4 +1,8 @@
|
|||||||
|
from time import sleep
|
||||||
|
|
||||||
|
from .schedule import Scheduler
|
||||||
from .simplesocket import ClientSocket
|
from .simplesocket import ClientSocket
|
||||||
|
from datetime import timedelta
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Callable, Dict, List, Union
|
from typing import Callable, Dict, List, Union
|
||||||
|
|
||||||
@ -365,3 +369,43 @@ class Client:
|
|||||||
|
|
||||||
def getChannelList(self) -> List[Channel]:
|
def getChannelList(self) -> List[Channel]:
|
||||||
return list(self.__channellist.values())
|
return list(self.__channellist.values())
|
||||||
|
|
||||||
|
|
||||||
|
class IrcBot(Client):
|
||||||
|
def __init__(self, server: str, port: int, nick: str, username: str, realname: str = "Python Bot"):
|
||||||
|
super().__init__(server, port, nick, username, realname)
|
||||||
|
self._scheduler = Scheduler()
|
||||||
|
self._channel_commands = {}
|
||||||
|
self._privmsg_commands = {}
|
||||||
|
self.subscribe(ServerMessage.MSG_PRIVMSG, self.on_privmsg)
|
||||||
|
|
||||||
|
def on(self, *args, **kwargs):
|
||||||
|
self.subscribe(*args, **kwargs)
|
||||||
|
|
||||||
|
def schedule(self, name: str, every: timedelta, func: Callable):
|
||||||
|
self._scheduler.schedule(name, every, func)
|
||||||
|
|
||||||
|
def register_channel_command(self, command: str, channel: str, func: Callable):
|
||||||
|
if channel not in self._channel_commands:
|
||||||
|
self._channel_commands[channel] = {}
|
||||||
|
|
||||||
|
self._channel_commands[channel][command] = func
|
||||||
|
|
||||||
|
def register_privmsg_command(self, command: str, func: Callable):
|
||||||
|
self._privmsg_commands[command] = func
|
||||||
|
|
||||||
|
def on_privmsg(self, msg_from, msg_to, message):
|
||||||
|
if not message:
|
||||||
|
return
|
||||||
|
command = message.split()[0]
|
||||||
|
if msg_to in self._channel_commands and command in self._channel_commands[msg_to]:
|
||||||
|
self._channel_commands[msg_to][command](msg_from, " ".join(message.split()[1:]))
|
||||||
|
|
||||||
|
if msg_to == self.getUser().nickname and command in self._privmsg_commands:
|
||||||
|
self._privmsg_commands[command](msg_from, " ".join(message.split()[1:]))
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
self._scheduler.run_pending()
|
||||||
|
self.receive()
|
||||||
|
sleep(0.01)
|
||||||
|
|||||||
6
tools/types.py
Normal file
6
tools/types.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from typing import Union
|
||||||
|
|
||||||
|
Numeric = Union[int, float]
|
||||||
|
IntOrNone = Union[int, None]
|
||||||
|
FloatOrNone = Union[float, None]
|
||||||
|
NumericOrNone = Union[Numeric, None]
|
||||||
Loading…
Reference in New Issue
Block a user