source: CSE3210/agent58/agent58.py

Last change on this file was 74, checked in by wouter, 21 months ago

#6 Added CSE3210 parties

File size: 6.2 KB
Line 
1import logging
2import time
3
4from typing import cast
5
6from geniusweb.actions.Accept import Accept
7from geniusweb.actions.Action import Action
8from geniusweb.actions.Offer import Offer
9from geniusweb.inform.ActionDone import ActionDone
10from geniusweb.inform.Finished import Finished
11from geniusweb.inform.Inform import Inform
12from geniusweb.inform.Settings import Settings
13from geniusweb.inform.YourTurn import YourTurn
14from geniusweb.party.Capabilities import Capabilities
15from geniusweb.party.DefaultParty import DefaultParty
16from geniusweb.profileconnection.ProfileConnectionFactory import (
17 ProfileConnectionFactory,
18)
19
20from .Constants import Constants
21from .acceptancestrategies.AcceptanceStrategy import AcceptanceStrategy
22from .biddingstrategies.TradeOff import TradeOff
23from .opponentmodels.OpponentModel import OpponentModel
24from geniusweb.progress.ProgressRounds import ProgressRounds
25from tudelft_utilities_logging.Reporter import Reporter
26
27
28class Agent58(DefaultParty):
29 """
30 Template agent that offers random bids until a bid with sufficient utility is offered.
31 """
32
33 def __init__(self, reporter: Reporter = None):
34 super().__init__(reporter)
35
36 self.getReporter().log(logging.INFO, "party is initialized")
37 self._profile = None
38 self._last_received_bid = None
39 self._received_bids = []
40 self._sent_bids = []
41 self.opponent_model = None
42 self.offer = Constants.offer
43 self.floor = Constants.floor
44 self.boulware = self.offer
45 self.bidding_strat = None
46 self.acceptance_strat = None
47
48 def notifyChange(self, info: Inform):
49 """This is the entry point of all interaction with your agent after is has been initialised.
50
51 Args:
52 info (Inform): Contains either a request for action or information.
53 """
54
55 # a Settings message is the first message that will be send to your
56 # agent containing all the information about the negotiation session.
57 if isinstance(info, Settings):
58 self._settings: Settings = cast(Settings, info)
59 self._me = self._settings.getID()
60
61 # progress towards the deadline has to be tracked manually through the use of the Progress object
62 self._progress = self._settings.getProgress()
63
64 # the profile contains the preferences of the agent over the domain
65 self._profile = ProfileConnectionFactory.create(
66 info.getProfile().getURI(), self.getReporter()
67 )
68
69 # BOA initializing
70 self.opponent_model = OpponentModel(self._profile.getProfile().getDomain())
71 # open('OpponentModel.log', 'w').close()
72 self.bidding_strat = TradeOff(self._profile.getProfile(), self.opponent_model, self.offer,
73 self._profile.getProfile().getDomain())
74 self.acceptance_strat = AcceptanceStrategy(self._profile.getProfile(), self.floor,
75 self._profile.getProfile().getDomain())
76
77 # ActionDone is an action send by an opponent (an offer or an accept)
78 elif isinstance(info, ActionDone):
79 action: Action = cast(ActionDone, info).getAction()
80
81 # if it is an offer, set the last received bid
82 if isinstance(action, Offer) and action.getActor().getName() != self._me.getName():
83 self._last_received_bid = cast(Offer, action).getBid()
84 self._received_bids.append(self._last_received_bid)
85 self.opponent_model.update_frequencies(self._last_received_bid)
86 # YourTurn notifies you that it is your turn to act
87 elif isinstance(info, YourTurn):
88 action = self._my_turn()
89 if isinstance(self._progress, ProgressRounds):
90 self._progress = self._progress.advance()
91 self.getConnection().send(action)
92
93 # Finished will be send if the negotiation has ended (through agreement or deadline)
94 elif isinstance(info, Finished):
95 # terminate the agent MUST BE CALLED
96 self.terminate()
97 else:
98 self.getReporter().log(
99 logging.WARNING, "Ignoring unknown info " + str(info)
100 )
101
102 # lets the geniusweb system know what settings this agent can handle
103 # leave it as it is for this competition
104 def getCapabilities(self) -> Capabilities:
105 return Capabilities(
106 set(["SAOP"]),
107 set(["geniusweb.profile.utilityspace.LinearAdditive"]),
108 )
109
110 # terminates the agent and its connections
111 # leave it as it is for this competition
112 def terminate(self):
113 self.getReporter().log(logging.INFO, "party is terminating:")
114 super().terminate()
115 if self._profile is not None:
116 self._profile.close()
117 self._profile = None
118
119
120
121 # give a description of your agent
122 def getDescription(self) -> str:
123 return "Trade-Off/TitForTat hyrbrid negotiation agent"
124
125 # Generate a variable that follows a boulware curve
126 def TimeDependent(self):
127 if self._progress.get(time.time() * 1000) > Constants.boulware_time_limit and self.offer > Constants.floor:
128 self.boulware = self.boulware - (Constants.boulware_conceding_speed * self._progress.get(time.time() * 1000))
129
130 # execute a turn
131 def _my_turn(self):
132 self.TimeDependent()
133 # generate a bid for the opponent
134 bid = self.bidding_strat.find_bid(self.opponent_model, self._last_received_bid, self._received_bids,
135 self._sent_bids, self.boulware)
136
137 # check if opponents bid is better than ours, if yes then accept, else offer our bid
138 if self.acceptance_strat.is_good(self._last_received_bid, bid, self._progress.get(time.time() * 1000)):
139 return Accept(self._me, self._last_received_bid)
140 else:
141 # save expected utility for OM graph
142 # with open("OpponentModel.log", "a") as text_file:
143 # text_file.write(str(self.opponent_model.utility(bid)) + "\n")
144
145 self._sent_bids.append(bid)
146 return Offer(self._me, bid)
Note: See TracBrowser for help on using the repository browser.