Changes between Version 11 and Version 12 of WikiStart


Ignore:
Timestamp:
07/27/21 13:30:44 (3 years ago)
Author:
Wouter Pasman
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • WikiStart

    v11 v12  
    3333
    3434
     35== Writing a party
     36Example parties can be found [source:/exampleparties here]. You can easily clone a party with SVN using {{{svn co https://tracinsy.ewi.tudelft.nl/pub/svn/GeniusWebPython/exampleparties/randomparty/}}} (this clones randomparty, use a different name to fetch another example).
     37
     38After cloning, create your venv and install the requirements, eg
     39{{{
     40python3 -m venv venv
     41source venv/bin/activate
     42pip install -r requirements.txt
     43}}}
     44
     45You can now run the junit tests.
     46
     47You may have to take different or additional steps if you use an IDE like eclipse with pydev, or pycharm.
     48
     49A party is compiled with python. Compile with {{{python3 setup.py sdist}}}. This gives you a  you get a {{{dist/yourparty-X.Y.Z.tar.gz}}} that can be copied into the pypartiesserver for deployment.
     50
     51The basic structure of a party that supports the SAOP behaviour looks like this
     52{{{
     53class RandomParty (DefaultParty):
     54    """
     55    Offers random bids until a bid with sufficient utility is offered
     56    """
     57    def __init__(self):
     58        super().__init__()
     59        self.getReporter().log(logging.INFO,"party is initialized")
     60        self._profile = None
     61        self._lastReceivedBid:Bid = None
     62
     63    def notifyChange(self, info: Inform):
     64        #self.getReporter().log(logging.INFO,"received info:"+str(info))
     65        if isinstance(info,Settings) :
     66            settings:Settings=cast(Settings,info)   
     67            self._me = settings.getID()
     68            self._protocol:str = str(settings.getProtocol().getURI())
     69            self._progress = settings.getProgress()
     70            if "Learn" ==  self._protocol:
     71                self.getConnection().send(LearningDone(self._me))
     72            else:
     73                self._profile = ProfileConnectionFactory.create(info.getProfile().getURI(), self.getReporter())
     74        elif isinstance(info, ActionDone):
     75            action:Action=cast( ActionDone,info).getAction()
     76            if isinstance(action, Offer):
     77                self._lastReceivedBid = cast(Offer, action).getBid()
     78        elif isinstance(info, YourTurn):
     79            self._myTurn()
     80            if isinstance(self._progress, ProgressRounds) :
     81                self._progress = self._progress.advance()
     82        elif isinstance(info, Finished):
     83            self.terminate()
     84        else:
     85            self.getReporter().log(logging.WARNING, "Ignoring unknown info "+str(info))
     86
     87
     88    def getCapabilities(self) -> Capabilities:
     89        return Capabilities( set([ "SAOP", "Learn"]), set(['geniusweb.profile.utilityspace.LinearAdditive']))
     90
     91    def getDescription(self) -> str:
     92        return "Offers random bids until a bid with sufficient utility is offered"
     93
     94    def _myTurn(self):
     95        if self._lastReceivedBid != None and \
     96            self._profile.getProfile().getUtility(self._lastReceivedBid) > 0.6:
     97            action = Accept(self._me, self._lastReceivedBid)
     98        else:
     99            for _attempt in range(20):
     100                bid = self._getRandomBid(self._profile.getProfile().getDomain())
     101                if self._isGood(bid):
     102                    break
     103            action = Offer(self._me, bid);
     104        self.getConnection().send(action)
     105
     106    def _isGood(self, bid:Bid)->bool:
     107        profile = self._profile.getProfile()
     108        return profile.getUtility(bid) > 0.6
     109
     110...
     111}}}
     112
     113The party must follow the behaviours that it promises. The example above folows the SAOP behaviour. 
     114
     115Notice, above is slightly simplified code, for fully working code check the [source:/exampleparties/randomparty/src/main/java/geniusweb/exampleparties/randomparty/RandomParty.java source code].
     116
     117=== Throwing exceptions
     118A special warning is in place regarding throwing exceptions from your implementation, particularly from notifyChange. In line with the general Listener interface, exceptions are only logged and your party usually is immediately disconnected if it throws any exception. Make sure that you free up any used resources to avoid memory leaks if you really need to throw an exception.
     119
     120=== Preparing the jar file
     121In order to put your party on the [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWebPartiesServer partiesserver] for running, you need a jar file of your party.
     122
     123Normally the party includes all dependencies. The jar files are loaded with an isolated jar class loader that should avoid collisions with possibly identically named but possibly different packages in other jar files.
     124
     125
     126Party jar files must have a Main-Class set in the MANIFEST.MF file. This main-class must implement Party and have a no-arg constructor.
     127
     128The example randomparty does this from the maven build script.
     129
     130We recommend to do initialization of the party only in the init() and not in the constructor or static code.
     131This because instances of your class can be made both for extracting general info as getDescription(), or to really run your class.
     132
     133
    35134== GeniusWeb sources
    36135