Package: diplomacy
Diplomacy: DATC-Compliant Game EngineThis 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.DocumentationThe complete documentation is available atdocs.diplomacy.ai.Getting StartedInstallationThe latest version of the package can be installed with:pipinstalldiplomacyThe package is compatible with Python 3.5, 3.6, and 3.7.Running a gameThe following script plays a game locally by submitting random valid orders until the game is completed.importrandomfromdiplomacyimportGamefromdiplomacy.utils.exportimportto_saved_game_format# Creating a game# Alternatively, a map_name can be specified as an argument. e.g. Game(map_name='pure')game=Game()whilenotgame.is_game_done:# Getting the list of possible orders for all locationspossible_orders=game.get_all_possible_orders()# For each power, randomly sampling a valid orderforpower_name,poweringame.powers.items():power_orders=[random.choice(possible_orders[loc])forlocingame.get_orderable_locations(power_name)ifpossible_orders[loc]]game.set_orders(power_name,power_orders)# Messages can be sent locally with game.add_message# e.g. game.add_message(Message(sender='FRANCE',#                               recipient='ENGLAND',#                               message='This is a message',#                               phase=self.get_current_phase(),#                               time_sent=int(time.time())))# Processing the game to move to the next phasegame.process()# Exporting the game to disk to visualize (game is appended to file)# Alternatively, we can do >> file.write(json.dumps(to_saved_game_format(game)))to_saved_game_format(game,output_path='game.json')Web interfaceIt is also possible to install a web interface in React to play against bots and/or other humans and to visualize games.The web interface can be installed with:# Install NVMcurl-o-https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh|bash# Clone repogitclonehttps://github.com/diplomacy/diplomacy.git# Install package locally# You may want to install it in a conda or virtualenv environmentcddiplomacy/
pipinstall-rrequirements_dev.txt# Build node modulescddiplomacy/web
npminstall.
npminstall.--only=dev# In a terminal window or tab - Launch React servernpmstart# In another terminal window or tab - Launch diplomacy serverpython-mdiplomacy.server.runThe web interface will be accessible athttp://localhost:3000.To 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.Visualizing a gameIt is possible to visualize a game by using the "Load a game from disk" menu on the top-right corner of the web interface.Network GameIt is possible to join a game remotely over a network using websockets. The script below plays a game over a network.Note. The server must be started withpython -m diplomacy.server.runfor the script to work.importasyncioimportrandomfromdiplomacy.client.connectionimportconnectfromdiplomacy.utilsimportexceptionsPOWERS=['AUSTRIA','ENGLAND','FRANCE','GERMANY','ITALY','RUSSIA','TURKEY']asyncdefcreate_game(game_id,hostname='localhost',port=8432):""" Creates a game on the server """connection=awaitconnect(hostname,port)channel=awaitconnection.authenticate('random_user','password')awaitchannel.create_game(game_id=game_id,rules={'REAL_TIME','NO_DEADLINE','POWER_CHOICE'})asyncdefplay(game_id,power_name,hostname='localhost',port=8432):""" Play as the specified power """connection=awaitconnect(hostname,port)channel=awaitconnection.authenticate('user_'+power_name,'password')# Waiting for the game, then joining itwhilenot(awaitchannel.list_games(game_id=game_id)):awaitasyncio.sleep(1.)game=awaitchannel.join_game(game_id=game_id,power_name=power_name)# Playing gamewhilenotgame.is_game_done:current_phase=game.get_current_phase()# Submitting ordersifgame.get_orderable_locations(power_name):possible_orders=game.get_all_possible_orders()orders=[random.choice(possible_orders[loc])forlocingame.get_orderable_locations(power_name)ifpossible_orders[loc]]print('[%s/%s] - Submitted:%s'%(power_name,game.get_current_phase(),orders))awaitgame.set_orders(power_name=power_name,orders=orders,wait=False)# Messages can be sent with game.send_message# await game.send_game_message(message=game.new_power_message('FRANCE', 'This is the message'))# Waiting for game to be processedwhilecurrent_phase==game.get_current_phase():awaitasyncio.sleep(0.1)# A local copy of the game can be saved with to_saved_game_format# To download a copy of the game with messages from all powers, you need to export the game as an admin# by logging in as 'admin' / 'password'asyncdeflaunch(game_id):""" Creates and plays a network game """awaitcreate_game(game_id)awaitasyncio.gather(*[play(game_id,power_name)forpower_nameinPOWERS])if__name__=='__main__':asyncio.run(launch(game_id=str(random.randint(1,1000))))LicenseThis project is licensed under the APGLv3 License - see theLICENSEfile for details