diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..56dbf89 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.10-buster + +LABEL authors="gfuse" + +RUN apt-get update && \ + apt-get install -y graphviz graphviz-dev && pip install graphviz + +WORKDIR /app + +COPY . /app + +RUN pip install . diff --git a/knight/__init__.py b/knight/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/knight/cell.py b/knight/cell.py new file mode 100644 index 0000000..b1ee9fe --- /dev/null +++ b/knight/cell.py @@ -0,0 +1,38 @@ +class Cell: + def __init__(self, pose: tuple = (0, 0), parent = None) -> None: + self.move = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)] + self.pose = pose + self.parent = parent + self.childs = [] + self.find = False + + def get_path(self) -> list: + path = [] + current = self + while current is not None: + path.append(current.pose) + current = current.parent + return path[::-1] + + def __eq__(self, other) -> bool: + return isinstance(other, Cell) and self.pose == other.pose + + def make_moves(self, destination, paths) -> None: + if isinstance(destination, Cell): + if len(self.childs) < 1: + for move in self.move: + x = self.pose[0] + move[0] + y = self.pose[1] + move[1] + if 0 <= x < 8 and 0 <= y < 8: + new_cell = Cell(pose=(x, y), parent=self) + if destination == new_cell: + self.find = True + paths.append(new_cell.get_path()) + else: + self.childs.append(new_cell) + if self.find: + self.childs.clear() + self.parent.childs.remove(self) + else: + for child in self.childs: + child.make_moves(destination, paths) diff --git a/knight/main.py b/knight/main.py new file mode 100644 index 0000000..77b24f6 --- /dev/null +++ b/knight/main.py @@ -0,0 +1,17 @@ +from knight.player import Player +import argparse +def main(): + parser = argparse.ArgumentParser( + prog='Knight', + description='', + epilog='') + parser.add_argument('-x', '--x_pose', help='Destination X between 0 and 8', type=int, required=True) + parser.add_argument('-y', '--y_pose', help='Destination Y between 0 and 8', type=int, required=True) + parser.add_argument('-n', '--image_name', help='Destination Y between 0 and 8', type=str, required=True) + args = parser.parse_args() + player = Player() + player.find_paths(destination=(args.x_pose,args.y_pose)) + player.plot_paths(name=args.image_name) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/knight/player.py b/knight/player.py new file mode 100644 index 0000000..32293c2 --- /dev/null +++ b/knight/player.py @@ -0,0 +1,29 @@ +from .cell import Cell +import logging +from graphviz import Digraph, render + +class Player(Cell): + def __init__(self) -> None: + super().__init__() + self.destination = None + self.paths = [] + self.depth = 0 + + def plot_paths(self, name:str = "shortest_paths") -> None: + dot = Digraph(comment='Paths') + for path in self.paths: + for i in range(len(path) - 1): + dot.edge(str(path[i]), str(path[i + 1])) + dot.save(f'{name}.dot') + render('dot', 'png', f'{name}.dot') + + + def find_paths(self, destination: tuple = (0, 0)): + self.destination = Cell(pose=destination) + if self.destination.pose[0] < 0 or self.destination.pose[1] > 8 or self.destination.pose[0] < 0 or self.destination.pose[1] > 8: + logging.error("Invalid destination position: it should be between 0 and 8") + return + while len(self.paths) < 1: + self.depth += 1 + self.make_moves(self.destination, self.paths) + diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..c3f8611 --- /dev/null +++ b/run.sh @@ -0,0 +1,6 @@ +if [ $1 == "build" ]; then + echo "Building docker image..."; + docker build -f Dockerfile -t knight:0.0 . +fi +echo "Run Knight ..."; +docker run -t -v ${PWD}:/app:rw --name knight knight:0.0 knight -x $2 -y $3 -n $4 \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..0debf4f --- /dev/null +++ b/setup.py @@ -0,0 +1,17 @@ +from setuptools import setup + +setup( + name='kiwifarm', + version='0.0', + packages=['knight'], + url='', + license='', + author='gfuse', + author_email='majidgeravand@gfuse.it', + description='knight problem', + entry_points={ + 'console_scripts': [ + 'knight=knight.main:main', + ], + }, +)