[96] | 1 | from __future__ import annotations
|
---|
| 2 | from typing import Set, Optional, List
|
---|
| 3 |
|
---|
| 4 | from geniusweb.actions.AbstractAction import AbstractAction
|
---|
| 5 | from geniusweb.actions.PartyId import PartyId
|
---|
| 6 | from geniusweb.actions.Vote import Vote
|
---|
| 7 | from geniusweb.issuevalue.Bid import Bid
|
---|
| 8 |
|
---|
| 9 |
|
---|
| 10 | class Votes (AbstractAction):
|
---|
| 11 | '''
|
---|
| 12 | Indicates that a party conditionally agrees with any of the {@link Vote}s
|
---|
| 13 | provided.
|
---|
| 14 | '''
|
---|
| 15 | def __init__(self, actor: PartyId, votes:Set[Vote]):
|
---|
| 16 | '''
|
---|
| 17 | @param id party id
|
---|
| 18 | @param votes the {@link Vote}s that the party can agree on, if the
|
---|
| 19 | condition of the Vote holds. Every {@link Vote#getActor()}
|
---|
| 20 | should equal the id. There may be at most 1 vote per
|
---|
| 21 | {@link Bid}.
|
---|
| 22 | '''
|
---|
| 23 | super().__init__(actor)
|
---|
| 24 | if votes == None:
|
---|
| 25 | raise ValueError("votes must be not null");
|
---|
| 26 | self._votes = votes.copy()
|
---|
| 27 | for vote in self._votes:
|
---|
| 28 | if not vote.getActor()== actor:
|
---|
| 29 | raise ValueError("All votes must come from "\
|
---|
| 30 | + str(actor) + " but found " + str(vote))
|
---|
| 31 |
|
---|
| 32 | # check for duplicate Vote's, possibly with different powers
|
---|
| 33 | votedfor:List[Bid] = []
|
---|
| 34 | for vote in votes:
|
---|
| 35 | bid = vote.getBid()
|
---|
| 36 | if bid in votedfor:
|
---|
| 37 | raise ValueError("Votes contains multiple Vote's for "+ str(bid))
|
---|
| 38 | votedfor.append(bid)
|
---|
| 39 |
|
---|
| 40 |
|
---|
| 41 | def isExtending(self, otherVotes:Votes ) -> bool:
|
---|
| 42 | '''
|
---|
| 43 | Test if Votes extends other votes. Extending means that for each vote on
|
---|
| 44 | bid B with power P in othervotes, this contains also a vote for bid B
|
---|
| 45 | with power at most P.
|
---|
| 46 |
|
---|
| 47 | @param otherVotes the {@link Votes}, usually from a previous round, that
|
---|
| 48 | this should extend.
|
---|
| 49 | @return true iff this extends the otherVotes.
|
---|
| 50 | '''
|
---|
| 51 | if not otherVotes.getActor()==self.getActor():
|
---|
| 52 | return False
|
---|
| 53 | for vote in otherVotes.getVotes():
|
---|
| 54 | myvote:Optional[Vote] = self.getVote(vote.getBid())
|
---|
| 55 | if myvote == None or myvote.getMinPower() > vote.getMinPower() or myvote.getMaxPower() < vote.getMaxPower(): # type:ignore
|
---|
| 56 | return False
|
---|
| 57 |
|
---|
| 58 | return True
|
---|
| 59 |
|
---|
| 60 |
|
---|
| 61 | def getVote(self, bid:Bid ) -> Optional[Vote] :
|
---|
| 62 | '''
|
---|
| 63 | @param bid the bid that we may have a vote for
|
---|
| 64 | @return myvote for bid, or null if no vote for that bid;
|
---|
| 65 | '''
|
---|
| 66 | for vote in self._votes:
|
---|
| 67 | if vote.getBid() == bid:
|
---|
| 68 | return vote;
|
---|
| 69 | return None;
|
---|
| 70 |
|
---|
| 71 | def getVotes(self) -> Set[Vote]:
|
---|
| 72 | return self._votes.copy()
|
---|
| 73 |
|
---|
| 74 |
|
---|
| 75 | def __eq__(self, other):
|
---|
| 76 | return isinstance(other, self.__class__) and \
|
---|
| 77 | self._actor==other._actor and self._votes==other._votes
|
---|
| 78 |
|
---|
| 79 | def __hash__(self):
|
---|
| 80 | return hash((self._actor, tuple(self._votes)))
|
---|
| 81 |
|
---|
| 82 | def __repr__(self) -> str :
|
---|
| 83 | return "Votes[" + str(self._actor) + "," +\
|
---|
| 84 | str(self._votes) + "]"
|
---|
| 85 |
|
---|