{ "info": { "author": "Philip Paquette", "author_email": "pcpaquette@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Games/Entertainment :: Board Games" ], "description": "# Diplomacy: DATC-Compliant Game Engine [![Build Status](https://travis-ci.org/diplomacy/diplomacy.svg?branch=master)](https://travis-ci.org/diplomacy/diplomacy) [![Documentation Status](https://readthedocs.org/projects/diplomacy/badge/?version=latest)](https://docs.diplomacy.ai/en/latest/?badge=latest)\n\nThis project contains an open-source DATC-compliant Diplomacy game engine, a client-server architecture for network play, a web interface to play against bots and to visualize games, and a DAIDE-compatible adapter to connect DAIDE bots to the server.\n\n

\n \"Diplomacy\n

\n\n## Documentation\n\nThe complete documentation is available at [docs.diplomacy.ai](https://docs.diplomacy.ai/).\n\n## Getting Started\n\n### Installation\n\nThe latest version of the package can be installed with:\n\n```python3\npip install diplomacy\n```\n\nThe package is compatible with Python 3.5, 3.6, and 3.7.\n\n### Running a game\n\nThe following script plays a game locally by submitting random valid orders until the game is completed.\n\n```python3\nimport random\nfrom diplomacy import Game\nfrom diplomacy.utils.export import to_saved_game_format\n\n# Creating a game\n# Alternatively, a map_name can be specified as an argument. e.g. Game(map_name='pure')\ngame = Game()\nwhile not game.is_game_done:\n\n # Getting the list of possible orders for all locations\n possible_orders = game.get_all_possible_orders()\n\n # For each power, randomly sampling a valid order\n for power_name, power in game.powers.items():\n power_orders = [random.choice(possible_orders[loc]) for loc in game.get_orderable_locations(power_name)\n if possible_orders[loc]]\n game.set_orders(power_name, power_orders)\n\n # Messages can be sent locally with game.add_message\n # e.g. game.add_message(Message(sender='FRANCE',\n # recipient='ENGLAND',\n # message='This is a message',\n # phase=self.get_current_phase(),\n # time_sent=int(time.time())))\n\n # Processing the game to move to the next phase\n game.process()\n\n# Exporting the game to disk to visualize (game is appended to file)\n# Alternatively, we can do >> file.write(json.dumps(to_saved_game_format(game)))\nto_saved_game_format(game, output_path='game.json')\n```\n\n## Web interface\n\nIt is also possible to install a web interface in React to play against bots and/or other humans and to visualize games.\n\nThe web interface can be installed with:\n\n```bash\n# Install NVM\ncurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash\n\n# Clone repo\ngit clone https://github.com/diplomacy/diplomacy.git\n\n# Install package locally\n# You may want to install it in a conda or virtualenv environment\ncd diplomacy/\npip install -r requirements_dev.txt\n\n# Build node modules\ncd diplomacy/web\nnpm install .\nnpm install . --only=dev\n\n# In a terminal window or tab - Launch React server\nnpm start\n\n# In another terminal window or tab - Launch diplomacy server\npython -m diplomacy.server.run\n```\n\nThe web interface will be accessible at http://localhost:3000.\n\nTo login, users can use admin/password or username/password. Additional users can be created by logging in with a username that does not exist in the database.\n\n![](docs/images/web_interface.png)\n\n### Visualizing a game\n\nIt is possible to visualize a game by using the \"Load a game from disk\" menu on the top-right corner of the web interface.\n\n![](docs/images/visualize_game.png)\n\n\n## Network Game\n\nIt is possible to join a game remotely over a network using websockets. The script below plays a game over a network.\n\nNote. The server must be started with `python -m diplomacy.server.run` for the script to work.\n\n```python3\nimport asyncio\nimport random\nfrom diplomacy.client.connection import connect\nfrom diplomacy.utils import exceptions\n\nPOWERS = ['AUSTRIA', 'ENGLAND', 'FRANCE', 'GERMANY', 'ITALY', 'RUSSIA', 'TURKEY']\n\nasync def create_game(game_id, hostname='localhost', port=8432):\n \"\"\" Creates a game on the server \"\"\"\n connection = await connect(hostname, port)\n channel = await connection.authenticate('random_user', 'password')\n await channel.create_game(game_id=game_id, rules={'REAL_TIME', 'NO_DEADLINE', 'POWER_CHOICE'})\n\nasync def play(game_id, power_name, hostname='localhost', port=8432):\n \"\"\" Play as the specified power \"\"\"\n connection = await connect(hostname, port)\n channel = await connection.authenticate('user_' + power_name, 'password')\n\n # Waiting for the game, then joining it\n while not (await channel.list_games(game_id=game_id)):\n await asyncio.sleep(1.)\n game = await channel.join_game(game_id=game_id, power_name=power_name)\n\n # Playing game\n while not game.is_game_done:\n current_phase = game.get_current_phase()\n\n # Submitting orders\n if game.get_orderable_locations(power_name):\n possible_orders = game.get_all_possible_orders()\n orders = [random.choice(possible_orders[loc]) for loc in game.get_orderable_locations(power_name)\n if possible_orders[loc]]\n print('[%s/%s] - Submitted: %s' % (power_name, game.get_current_phase(), orders))\n await game.set_orders(power_name=power_name, orders=orders, wait=False)\n\n # Messages can be sent with game.send_message\n # await game.send_game_message(message=game.new_power_message('FRANCE', 'This is the message'))\n\n # Waiting for game to be processed\n while current_phase == game.get_current_phase():\n await asyncio.sleep(0.1)\n\n # A local copy of the game can be saved with to_saved_game_format\n # To download a copy of the game with messages from all powers, you need to export the game as an admin\n # by logging in as 'admin' / 'password'\n\nasync def launch(game_id):\n \"\"\" Creates and plays a network game \"\"\"\n await create_game(game_id)\n await asyncio.gather(*[play(game_id, power_name) for power_name in POWERS])\n\nif __name__ == '__main__':\n asyncio.run(launch(game_id=str(random.randint(1, 1000))))\n\n```\n## License\n\nThis project is licensed under the APGLv3 License - see the [LICENSE](LICENSE) file for details", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/diplomacy/diplomacy", "keywords": "diplomacy diplomacy-game game negotiation", "license": "", "maintainer": "", "maintainer_email": "", "name": "diplomacy", "package_url": "https://pypi.org/project/diplomacy/", "platform": "", "project_url": "https://pypi.org/project/diplomacy/", "project_urls": { "Bug Reports": "https://github.com/diplomacy/diplomacy/issues", "Documentation": "https://docs.diplomacy.ai/", "Homepage": "https://github.com/diplomacy/diplomacy", "Source": "https://github.com/diplomacy/diplomacy/" }, "release_url": "https://pypi.org/project/diplomacy/1.1.1/", "requires_dist": null, "requires_python": ">=3.5", "summary": "Diplomacy: DATC-Compliant Game Engine with Web Interface", "version": "1.1.1" }, "last_serial": 5830392, "releases": { "1.0.1": [ { "comment_text": "", "digests": { "md5": "2a7191c59163e03000e492a32a38fc5e", "sha256": "3227b45ca0afe49fcd7bcaa58ed0d802ae42972dbed64ece414f28caa22998a8" }, "downloads": -1, "filename": "diplomacy-1.0.1.tar.gz", "has_sig": false, "md5_digest": "2a7191c59163e03000e492a32a38fc5e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 754474, "upload_time": "2019-09-01T20:58:52", "url": "https://files.pythonhosted.org/packages/8f/ca/34aed4e7b821f8ab8decef56b29813b89a25e6b7aee4338c42fcb22d08bc/diplomacy-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "0185a51c6b48a05832eab279c7f943b9", "sha256": "6a6037964d7e226a7456fb9255075ff5d976aea3fca6ffdd12c01d409d1b0835" }, "downloads": -1, "filename": "diplomacy-1.1.0.tar.gz", "has_sig": false, "md5_digest": "0185a51c6b48a05832eab279c7f943b9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1258262, "upload_time": "2019-09-03T19:22:26", "url": "https://files.pythonhosted.org/packages/b9/43/3ccfa091ea417dd4e470b1b266d545cd2f7a9a950ea984adc2d2ae102be7/diplomacy-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "de0c242a51f8944a146a53ef0b6ab654", "sha256": "9010ef474011cf0b206efb6aa418c72d4cb83df851f442d3f15a7d9d48cbcf1b" }, "downloads": -1, "filename": "diplomacy-1.1.1.tar.gz", "has_sig": false, "md5_digest": "de0c242a51f8944a146a53ef0b6ab654", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 2179604, "upload_time": "2019-09-14T22:26:12", "url": "https://files.pythonhosted.org/packages/dc/8f/e21d66441f1dde89eb969cb2d8e6e92440e3b4ec812171c1ebc52a74fe00/diplomacy-1.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "de0c242a51f8944a146a53ef0b6ab654", "sha256": "9010ef474011cf0b206efb6aa418c72d4cb83df851f442d3f15a7d9d48cbcf1b" }, "downloads": -1, "filename": "diplomacy-1.1.1.tar.gz", "has_sig": false, "md5_digest": "de0c242a51f8944a146a53ef0b6ab654", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 2179604, "upload_time": "2019-09-14T22:26:12", "url": "https://files.pythonhosted.org/packages/dc/8f/e21d66441f1dde89eb969cb2d8e6e92440e3b4ec812171c1ebc52a74fe00/diplomacy-1.1.1.tar.gz" } ] }