Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • Davide.Lanti1/wumpus-tessaris-1
  • Davide.Lanti1/wumpus-tessaris
  • Asma.Tajuddin/wumpus
  • Ali.Ahmed/wumpus
  • Sanaz.Khosropour/wumpus
  • PetroMakanza.Joseph/wumpus
  • tessaris/wumpus
7 results
Show changes
Commits on Source (10)
......@@ -9,22 +9,22 @@ The package has been written to be used in the master course of AI taught at the
You can download the source code from <https://gitlab.inf.unibz.it/tessaris/wumpus> and use `pip install .`, or install directly from the repository using
```
pip install https://gitlab.inf.unibz.it/tessaris/wumpus/-/archive/master/wumpus-master.tar.gz
pip install git+https://gitlab.inf.unibz.it/tessaris/wumpus.git@master
```
## Usage
To write your own player you should create a subclass of `Player` (defined in [gridworld.py](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/wumpus/gridworld.py)) and then use an instance as a parameter of the `run_episode` method of `GridWorld` class (defined in [gridworld.py](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/wumpus/gridworld.py)).
To write your own player you should create a subclass of `OnlinePlayer` or `OfflinePlayer` (defined in [player.py](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/wumpus/player.py)) and then use an instance as a parameter of the `run_episode` function (defined in [runner.py](https://gitlab.inf.unibz.it/tessaris/wumpus/-/blob/master/wumpus/runner.py)).
Examples of the usage of the package can be found in the implementation of two players `RandomPlayer` and `UserPlayer` from [gridworld.py](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/wumpus/gridworld.py), and in the files [`wumpus-usage.py`](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/examples/wumpus-usage.py), [`eater-usage.py`](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/examples/eater-usage.py) in the [`examples`](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/examples) directory of the repository.
Examples of the usage of the package can be found in the implementation of two players `RandomPlayer` and `UserPlayer` in [player.py](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/wumpus/player.py), and in the files [`wumpus_usage.py`](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/examples/wumpus_usage.py), [`eater_usage.py`](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/examples/eater_usage.py) in the [`examples`](https://gitlab.inf.unibz.it/tessaris/wumpus/blob/master/examples) directory of the repository.
Your player could be also run using the script `gridrunner` script (in the repository is the `runner.py` file) and it'll be available once the package is installed (in alternative could be executed using `python -m wumpus.runner`):
Your player could be also run using the script `gridrunner` script (in the repository is the [`cli.py`](https://gitlab.inf.unibz.it/tessaris/wumpus/-/blob/master/wumpus/cli.py) file) and it'll be available once the package is installed (in alternative could be executed using `python -m wumpus.cli`):
```
``` bash
$ gridrunner --help
usage: gridrunner [-h] [--name NAME] [--path PATH] --entry ENTRY
[--world {EaterWorld,WumpusWorld}] [--horizon HORIZON]
[--noshow] [--out OUT] [--version]
[--noshow] [--out OUT] [--version] [--log LOG]
[infiles [infiles ...]]
Run episodes on worlds using the specified player.
......@@ -54,31 +54,32 @@ optional arguments:
--out OUT, -o OUT write output to file (default: <_io.TextIOWrapper
name='<stdout>' mode='w' encoding='UTF-8'>)
--version show program's version number and exit
--log LOG, -l LOG write the log of the games to file (JSON) (default:
None)
```
For example:
``` bash
$ gridrunner --world EaterWorld --entry wumpus:RandomPlayer --noshow --horizon 5 --path examples ./examples/eater-world.json
┌────────┐
│.....│
│.██...│
│.....│
│.....│
│🍌🐒.🍌.│
└────────┘
Step 0: agent Eater_df9919cd executing W -> reward 9
Step 1: agent Eater_df9919cd executing S -> reward -1
Step 2: agent Eater_df9919cd executing N -> reward -1
Step 3: agent Eater_df9919cd executing W -> reward -1
Step 4: agent Eater_df9919cd executing N -> reward -1
$ gridrunner --world EaterWorld --entry wumpus:RandomPlayer --noshow --horizon 5 ./examples/eater-world.json
Step 0: agent Eater_c881e1b0 executing N -> reward -1
Step 1: agent Eater_c881e1b0 executing W -> reward -1
Step 2: agent Eater_c881e1b0 executing E -> reward -1
Step 3: agent Eater_c881e1b0 executing W -> reward -1
Step 4: agent Eater_c881e1b0 executing E -> reward -1
Episode terminated by maximum number of steps (5).
┌─────────┐
┌─────────
│.....│
│.██...│
│🐒....│
│.....│
│...🍌.│
└─────────┘
Episode terminated with a reward of 5 for agent Eater_df9919cd
│.🐒...│
│🍌..🍌.│
└──────────┘
Episode terminated with a reward of -5 for agent Eater_c881e1b0
```
You can also use a player defined in a script; e.g., if the player class `GooPlayer` is defined in the `eater_usage.py` you can use the `eater_usage:GooPlayer` entry. Remember Python rules for finding modules, where the current directory is added to the search path. If the script is in a different directory, you can use the `--path` argument to tell the script where to find it:
```bash
gridrunner --world EaterWorld --entry eater_usage:GooPlayer --path examples --noshow --horizon 5 ./examples/eater-world.json
```
\ No newline at end of file
name: wumpus
channels:
- conda-forge
- nodefaults
dependencies:
- python>=3.6
- gym
- python>=3.8
- gym<=0.22
- pip
- pip:
- wumpus[gym] @ git+https://gitlab.inf.unibz.it/tessaris/wumpus.git
\ No newline at end of file
- wumpus @ https://gitlab.inf.unibz.it/tessaris/wumpus/-/archive/dev/wumpus-dev.zip
\ No newline at end of file
[metadata]
name = wumpus
version = attr:wumpus.__version__
description = This package implements a Python version of the Hunt the Wumpus game as described in the book Artificial Intelligence: A Modern Approach by Russell and Norvig.
long_description = file: README.md
license = MIT
author = Sergio Tessaris
author_email = tessaris@inf.unibz.it
[options]
zip_safe = False
include_package_data = True
packages = find:
python_requires = >=3.8
install_requires =
gym < 0.24
[options.entry_points]
console_scripts =
gridrunner = wumpus.cli:main
from setuptools import setup, find_packages
import re
import codecs
import os
import subprocess
#!/usr/bin/env python
import setuptools
# Hack to allow non-normalised versions
# see <https://github.com/pypa/setuptools/issues/308>
from setuptools.extern.packaging import version
version.Version = version.LegacyVersion
_INCLUDE_GIT_REV_ = False
# see <https://stackoverflow.com/a/39671214> and
# <https://packaging.python.org/guides/single-sourcing-package-version>
def find_version(*pkg_path):
pkg_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), *pkg_path)
version_file = codecs.open(os.path.join(pkg_dir, '__init__.py'), 'r').read()
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
version_file, re.M)
_git_revision_ = None
if _INCLUDE_GIT_REV_:
try:
_git_revision_ = subprocess.check_output(['git', 'describe', '--always', '--dirty'], encoding='utf-8').strip()
except subprocess.CalledProcessError:
pass
if version_match:
return version_match.group(1) + ('' if _git_revision_ is None else '+' + _git_revision_)
elif _git_revision_:
return _git_revision_
raise RuntimeError("Unable to find version string.")
def long_description_md(fname='README.md'):
this_directory = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(this_directory, fname), encoding='utf-8') as f:
long_description = f.read()
return long_description
setup(
name='wumpus',
version=find_version('wumpus'),
description='Wumpus world simulator',
long_description=long_description_md(),
long_description_content_type='text/markdown',
author='Sergio Tessaris',
author_email='tessaris@inf.unibz.it',
packages=find_packages(),
include_package_data=True,
entry_points= {
'console_scripts': ['gridrunner=wumpus.cli:main']
},
install_requires=[
],
extras_require={
'gym': ['gym']
},
exclude_package_data={'': ['.gitignore']},
)
if __name__ == "__main__":
setuptools.setup()
\ No newline at end of file
......@@ -3,4 +3,4 @@ from .player import OfflinePlayer, OnlinePlayer, UserPlayer, RandomPlayer
from .wumpus import WumpusWorld, Hunter, Wumpus, Pit, Gold, Exit
from .runner import run_episode
__version__ = '1.0.0'
__version__ = '1.1.0'
......@@ -7,6 +7,7 @@ Functions to run the players
import argparse
import copy
import importlib
import inspect
import io
import json
import os
......@@ -51,17 +52,20 @@ def get_player_class(object_ref: str, path: os.PathLike = None) -> Union[Type[On
# see <https://packaging.python.org/specifications/entry-points/#data-model>
modname, qualname_separator, qualname = object_ref.partition(':')
obj = importlib.import_module(modname)
try:
obj = importlib.import_module(modname)
except ModuleNotFoundError as e:
raise ImportError(f'Cannot find entrypoint {object_ref}: {e}')
if qualname_separator:
for attr in qualname.split('.'):
try:
obj = getattr(obj, attr)
except AttributeError as e:
raise ImportError('Cannot import {} object: {}'.format(object_ref, e))
raise ImportError(f'Cannot find entrypoint {object_ref}: {e}')
player_class = obj
if not issubclass(player_class, (OnlinePlayer, OfflinePlayer)):
raise NotImplementedError('class {} is not a player class'.format(player_class))
if not inspect.isclass(player_class) or not issubclass(player_class, (OnlinePlayer, OfflinePlayer)):
raise RuntimeError(f'{player_class} is not a subclass of OnlinePlayer or OfflinePlayer')
return player_class
......
......@@ -272,7 +272,7 @@ class WumpusWorld(GridWorld):
else:
return [getCoord(data)]
size = next(coordLst('size'))
size = getCoord(desc.get('size', [8, 8]))
blocks = coordLst('blocks')
hunters = desc.get('hunters', [])
pits = coordLst('pits')
......