예제 #1
0
  def setUp(self):
    self.player = SillyPlayer(1, [], 0)
    self.strat = strategy.Strategy()

    self.carnivore = species.Species(0, 1, 1, [])
    self.carnivore.setTraits([trait.Trait.carnivore])
    self.fat_carnivore = species.Species(0, 1, 1, [])
    self.fat_carnivore.setTraits([trait.Trait.carnivore])
    self.fat_carnivore.setBodySize(5)

    self.herbavore = species.Species(0, 1, 1, [])
    self.fat_herbavore = species.Species(0, 1, 1, [])
    self.fat_herbavore.setBodySize(4)

    self.fat_tissue = species.Species(0, 1, 1, [])
    self.fat_tissue.setBodySize(3)
    self.fat_tissue.setTraits([trait.Trait.fat_tissue])
    self.fat_fat_tissue = species.Species(0, 1, 1, [])
    self.fat_fat_tissue.setBodySize(6)
    self.fat_fat_tissue.setTraits([trait.Trait.fat_tissue])

    self.opherb = species.Species(0, 1, 1, [])
    self.opfatherb = species.Species(0, 1, 1, [])
    self.opfatherb.setBodySize(4)

    self.opponent1 = SillyPlayer(1, [], 0)
    self.opponent1.setSpeciesBoards([self.opherb, self.opfatherb])
    self.opponents = [[self.opherb, self.opfatherb]]

    self.dealer = dealer.Dealer(4, [self.player, self.opponent1])
예제 #2
0
 def __init__(self, id, bag, speciesList, cards, player=None, info=""):
     self.num = id
     self.foodbag = bag
     self.species = speciesList
     self.hand = cards
     self.player = player or SillyPlayer()
     self.info = info
예제 #3
0
def parse_playerEx(player_json):
	"""
	converts the json representation of a player into a player representation
	:param player_json: Player+
	:return: Player
	"""
	try:
		if len(player_json) == 4:
			[[i, given_id], [l, los], [b, bag], [c, loc]] = player_json
			if (i == "id" and l == "species" and b == "bag" and c == "cards"):
				player = SillyPlayer(given_id, parse_los(los), bag)
				if loc:
					player.setHand(parse_loc(loc))
					return player
				else:
					return player
		else:
			[[i, given_id], [l, los], [b, bag]] = player_json
			if (i == "id" and l == "species" and b == "bag"):
				return SillyPlayer(given_id, parse_los(los), bag)
	except ValueError:
		raise ValueError("invalid player")
예제 #4
0
 def __init__(self, ident, loSpeciesBoard, bag, externalPlayer = None, info = None):
   """
   Initializes a player with a given id, list of species boards, and food bag
   :param ident: int
   :param loSpeciesBoard: list of Species
   :param bag: int greater than 0
   :param externalPlayer: a an extenal player (SillyPlayer or ProxyPlayer)
   :param info: String
   """
   self.species_boards = loSpeciesBoard
   self.food_bag = bag
   self.hand = []
   self.player_id = ident
   if externalPlayer:
     self.externalPlayer = externalPlayer
   else:
     self.externalPlayer = SillyPlayer(1, [], 0)
   if info:
     self.info = info
   else:
     self.info = ""
예제 #5
0
class PlayerState:
    num = 0
    foodbag = 0
    species = []
    hand = []
    """ 
		Internal representation of a json player
		@param num: Nat+ representing this player's unique ID number
		@param foodbag: Nat representing this player's foodbag
		@param species: A List of this player's Species boards
		@param hand: A List of TraitCards in this player's hand (not on boards/haven't been traded in)
		@param player: the external player with strategic functionality
		Nat, Nat, ListOf(Species), ListOf(TraitCard), Player -> PlayerState
	"""
    def __init__(self, id, bag, speciesList, cards, player=None):
        self.num = id
        self.foodbag = bag
        self.species = speciesList
        self.hand = cards
        self.player = SillyPlayer()

    """ 
		override equality
		Any -> Boolean
	"""

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        else:
            return False

    """ 
		override inequality
		Any -> Boolean
	"""

    def __ne__(self, other):
        return not self.__eq__(other)

    """
		start a game (step 1) -- if given a new species, add it, and inform external player of current state
		@param spec: an OptSpecies (given if this player didn't already have a species; otherwise False)
		OptSpecies -> Void
	"""

    def start(self, spec):
        if spec is not False:
            self.species.append(spec)
        self.player.start(self)

    """
		Do post-turn cleanup:
		- square up species' populations with what they ate
		- remove starving species
		- move food from species boards to player foodbags
		@return the number of species we removed for being extinct (so that dealer can give us cards)
		Void -> Nat
	"""

    def endOfTurn(self):
        numExtinct = 0
        speciesToRemove = []
        for specIdx in range(len(self.species)):
            self.foodbag += self.species[specIdx].cullStarving()
            if self.isExtinct(specIdx):
                speciesToRemove.append(specIdx)
                numExtinct += 1

        self.species = [
            self.species[i] for i in range(len(self.species))
            if i not in speciesToRemove
        ]
        return numExtinct

    """
		Check if an action from our external player would be a cheating move
		Following conditions must pass:
			- All card indexes acted on must exist in our hand and be unique 
			- The highest species index referenced should exist after addition of new species boards
			- Should only be able to replace trait cards that already exist (ie no adding of new trait cards)
		@param action: the action the external player wishes to take
		@return the action or, if it was cheating, False
		Action4 -> Action4 or False
	"""

    def checkCheatAction(self, action):
        if (self.checkLegalCards(action.getAllCardIdcs())
                and self.checkLegalSpecies(action.getAllSpecIdcs(),
                                           len(action.BT))
                and self.checkTraitReplacement(action.RT, action.BT)):
            return action
        else:
            return False

    """
		Check that all species indexes passed correspond to species that
		the player will own by the end of the action
		Used to check for cheating in Action4
		@param specIdcs: indexes of the species the external player asked to modify
		@param numBT: the number of BuyTrait actions being requested
		@return True if moves are legal, False otherwise
		ListOf(Nat) -> Boolean
	"""

    def checkLegalSpecies(self, specIdcs, numBT):
        return not ((max(specIdcs) >
                     (numBT + len(self.species) - 1)) or (min(specIdcs) < 0))

    """
		Check that trait replacement uses legal cards and tries to replace existing traits
		Used to check for cheating in Action4
		@param RTs: the ReplaceTrait actions to check
		@param BTs: the BuySpeciesBoards
		@return True if moves are legal, False otherwise
		ListOf(ReplaceTrait) -> Boolean
	"""

    def checkTraitReplacement(self, RTs, BTs):
        for rt in RTs:
            if (rt.oldTraitIdx < 0) or (rt.specIdx >
                                        (len(self.species) + len(BTs) - 1)):
                return False

            traitLen = False
            if rt.specIdx < len(self.species):
                traitLen = len(self.species[rt.specIdx].traits)
            elif rt.specIdx < (len(self.species) + len(BTs)):
                traitLen = len(BTs[rt.specIdx - len(self.species) -
                                   1].traitList)

            if traitLen is False or rt.oldTraitIdx >= traitLen:
                return False

        return True

    """
		Check that the card indexes passed all correspond to cards we own
		and that each index is unique
		Used to check for cheating in an Action4
		@param cardIdcs: the indexes of the cards the external player asked to use
		@return True if the moves are legal, False otherwise
		ListOf(Nat) -> Boolean
	"""

    def checkLegalCards(self, cardIdcs):
        if len(cardIdcs) != len(set(cardIdcs)):  # no duplicates
            return False
        if (max(cardIdcs) >
            (len(self.hand) -
             1)) or min(cardIdcs) < 0:  # only use cards we have
            return False
        return True

    """
		Choose actions for watering hole tributes and trading and check for cheating
		assumption: list of players is ordered such that players before this one in the list
					play before us, and those after this one in the list play after us
		@param allPlayers: the states of all players currently in the game
		@return an Action4 from the external player or, if that move was cheating, False
		ListOf(PlayerState) -> Action4 or False
	"""

    def choose(self, allPlayers):
        for i in range(len(allPlayers)):
            if allPlayers[i] is self:
                splitIdx = i
        befores = [play.species for play in allPlayers[:splitIdx]]
        afters = [play.species for play in allPlayers[splitIdx + 1:]]

        return self.checkCheatAction(self.player.choose(befores, afters))

    """
		create dictionary 
		None -> Dict
	"""

    def toDict(self):
        return {
            "num": self.num,
            "species": [species.toDict() for species in self.species],
            "hand": [card.toDict() for card in self.hand],
            "foodbag": self.foodbag
        }

    """
		Display the essence of a player
		Void -> Void
	"""

    def display(self):
        Drawing(player=self.toDict())

    """ 
	   creates a json array of a PlayerState object
	   Void -> JsonArray
	"""

    def playerStateToJson(self):
        species = [Species.speciesToJson(animal) for animal in self.species]
        cards = [TraitCard.traitCardToJson(card) for card in self.hand]

        result = [["id", self.num], ["species", species],
                  ["bag", self.foodbag]]

        if cards:
            result.append(["cards", cards])

        return result

    """
	   creates a PlayerState from a json array
	   JsonArray -> PlayerState
	"""

    @staticmethod
    def playerStateFromJson(state):
        try:
            cards = []
            if state[0][0] == "id":
                num = state[0][1]
            if state[1][0] == "species":
                speciesList = [
                    Species.speciesFromJson(species) for species in state[1][1]
                ]
            if state[2][0] == "bag":
                bag = state[2][1]
            if len(state) == 4 and state[3][0] == "cards":
                cards = [
                    TraitCard.traitCardFromJson(card) for card in state[3][1]
                ]
            if num > 0 and bag >= 0:
                return PlayerState(num, bag, speciesList, cards)

        except Exception as e:
            print state
            raise e
            #quit()

    """
		Proxy to call the feed method in the external player
		@param wateringHole: the amount of food that can be eaten
		@param players: all the players in this round
		@return FeedingAction -One of:
			False - no feeding at this time
			Nat - index of Species fed
			[Nat, Nat] - index of fat-tissue Species fed, amount of fatFood
			[Nat, Nat, Nat] - index of carnivore, index of player to attack, index of species to attack
		Nat, ListOf(PlayerState) -> FeedingAction
	"""

    def feed(self, wateringHole, player):
        return self.player.feed(self, wateringHole, player)

    """
		Get this player's score -- a combo of their foodbag, total population 
		for all species, and total trait cards placed on species
		@return the player's score based on the above
		Void -> Nat
	"""

    def getScore(self):
        score = self.foodbag
        for spec in self.species:
            score += spec.population
            score += len(spec.traits)

        return score

    """
		Number of cards this player needs dealt at the beginning of a turn
		Based on their number of species
		If they have no species, then they should ask for 1 card, as they'll be receiving a new species
		at the beginning of the round
		@return num cards needed
		Void -> Nat
	"""

    def numCardsNeeded(self):
        return 3 + max(1, len(self.species))

    """
		Filter out all fed species to get a list of species that can be fed
		@return a list of (Species' index, Species) for hungry species this player has
		Void -> ListOf((Nat, Species))
	"""

    def getHungrySpecies(self):
        hungry = []
        for i in range(len(self.species)):
            if self.species[i].isHungry():
                hungry.append((i, self.species[i]))

        return hungry

    """
		Gets the indexes of the species neighboring the given species
		@param speciesIdx: index of the species to get neighbors for
		Nat -> [OptSpecies, OptSpecies] where an OptSpecies is Species or False
	"""

    def getNeighbors(self, speciesIdx):
        if speciesIdx > 0:
            lNeighbor = self.species[speciesIdx - 1]
        else:
            lNeighbor = False

        if speciesIdx < len(self.species) - 1:
            rNeighbor = self.species[speciesIdx + 1]
        else:
            rNeighbor = False

        return [lNeighbor, rNeighbor]

    """
		Verify that this player can use their own chosen species to attack the other given species
		@param defPlayer: PlayerState of the defending player
		@param defIdx: index of the defending species
		@param attIdx: index of the attacking species: should be one of our own
		PlayerState, Nat, Nat -> Boolean
	"""

    def verifyAttack(self, defPlayer, attIdx, defIdx):
        left, right = defPlayer.getNeighbors(defIdx)
        return Species.isAttackable(defPlayer.species[defIdx],
                                    self.species[attIdx], left, right)

    """
		Tell whether or not the given species is extinct (i.e. that its population <= 0)
		@param specIdx: index of the species to check
		Nat -> Boolean
	"""

    def isExtinct(self, specIdx):
        return self.species[specIdx].isExtinct()

    """
		Add one population to a species at the given index
		@param specIdx: index of the species to modify
		Nat -> Void
	"""

    def addPopulation(self, specIdx):
        self.species[specIdx].addPopulation()

    """
		Add one body size to a species at the given index
		@param specIdx: index of the species to modify
		Nat -> Void
	"""

    def addBody(self, specIdx):
        self.species[specIdx].addBody()

    """
		Give this player a new species with the given traits
		@param traitIdcs: indices of the trait cards this new species will have, up to 3
		ListOf(Nat) -> Void
	"""

    def addSpecies(self, traitIdcs):
        self.species.append(
            Species(0, 0, 1, [self.hand[i] for i in traitIdcs], 0))

    """
		Remove the given species from this player's list of species
		@param specIdx: index of the species to remove
		Nat -> Void
	"""

    def removeSpecies(self, specIdx):
        del self.species[specIdx]

    """
		Tell whether or not this player has any species
		Void -> Boolean
	"""

    def hasNoSpecies(self):
        return not (len(self.species) > 0)

    """
		Deletes the cards at the given indices from this player's hand
		@param cardIdcs: the indexes of the cards to remove
		ListOf(Nat) -> Void
	"""

    def discardFromHand(self, cardIdcs):
        self.hand = [
            self.hand[i] for i in range(len(self.hand)) if i not in cardIdcs
        ]

    """
		Adds the given TraitCards to the end of this player's hand
		@param cards: the cards to add
		ListOf(TraitCard) -> Void 

	"""

    def addCards(self, cards):
        self.hand = cards + self.hand

    """
		Tell whether the species at the given index has the given trait
		@param specIdx: the index of the species to check
		@param traitName: the name of the trait to check for
		Nat, String -> Boolean
	"""

    def speciesHasTrait(self, specIdx, traitName):
        return self.species[specIdx].hasTrait(traitName)

    """
		Drop the population of the given species as in a carnivore attack
		If the species' food > its population, drop the food as well
		@param specIdx: the index of the species to have its population decremented
		Nat -> Void
	"""

    def executeAttack(self, specIdx):
        self.species[specIdx].executeAttack()

    """
		Feed the given species the given amount of fat food that it requested
		@param specIdx: index of the species to feed
		@param foodCount: amount of food to try to feed
		@return the amount of food this species was given
		Nat, Nat -> Nat
	"""

    def feedFatFood(self, specIdx, foodCount):
        spec = self.species[specIdx]
        if spec.hasTrait("fat-tissue"):
            foodCount = min(foodCount, spec.body - spec.fatFood)
            spec.eatFatFood(foodCount)
            return foodCount
        else:
            raise ValueError(
                "Tried to feed fat food to a species without fat tissue")

    """
		Feed a given species the amount of food that it requested
		@param specIdx: index of the species to feed
		@param foodCount: amount of food to try to feed
		@param wateringHole: the amount of food in the dealer's watering hole
		@return the total amount of food eaten during this feeding
		Nat, Nat, Nat -> Nat
	"""

    def feedSpecies(self, specIdx, foodCount, wateringHole):
        spec = self.species[specIdx]
        foodCount = min(wateringHole, foodCount, spec.population - spec.food)
        spec.eatFood(foodCount)
        wateringHole -= foodCount

        forageAmount = self.forage(specIdx, wateringHole)
        wateringHole -= forageAmount
        foodCount += forageAmount

        foodCount += self.cooperate(specIdx, foodCount, wateringHole)

        return foodCount

    # TODO: abstract everything. all of it
    """
		If the given species has the foraging trait, give it one more food
		@param specIdx: index of the species to feed
		@param wateringHole: the amount of food in the dealer's watering hole
		@return the amount of food this species ate
	"""

    def forage(self, specIdx, wateringHole):
        spec = self.species[specIdx]
        amountFed = 0
        if wateringHole > 0 and spec.hasTrait(
                "foraging") and spec.population > spec.food:
            spec.eatFood(1)
            amountFed += 1

        return amountFed

    """
		Cooperate
		@param specIdx: index of the species to feed
		@param foodCount: amount of food to try to feed
		@param wateringHole: the amount of food in the dealer's watering hole
		@return the amount of food all species in the cooperation chain ate
		Nat, Nat, Nat -> Nat
	"""

    def cooperate(self, specIdx, foodCount, wateringHole):
        spec = self.species[specIdx]
        amountFed = 0
        left, right = self.getNeighbors(specIdx)
        if spec.hasTrait("cooperation") and right is not False:
            for i in range(foodCount):
                if wateringHole > 0:
                    fedThisSpecies = self.feedSpecies(specIdx + 1, 1,
                                                      wateringHole)
                    amountFed += fedThisSpecies
                    wateringHole -= fedThisSpecies

        return amountFed

    """
		After a carnivore attack, have all species with the scavenge trait eat from left to right
		@param wateringHole: the amount of food that can be handed out amongst the scavengers
		@return the amount of food eaten amongst our scavengers
		Nat -> Nat
	"""

    def scavenge(self, wateringHole):
        amountFed = 0
        scavengers = self.getSpeciesWithTrait("scavenger")
        for scav in scavengers:
            if wateringHole > 0:
                fedThisSpecies = self.feedSpecies(scav, 1, wateringHole)
                amountFed += fedThisSpecies
                wateringHole -= fedThisSpecies
        return amountFed

    """
		Get all species this player owns that has the given trait 
		@param trait: the name of the trait to be checked
		String -> ListOf(SpecIdx)
	"""

    def getSpeciesWithTrait(self, trait):
        return [
            i for i in range(len(self.species))
            if self.speciesHasTrait(i, trait)
        ]

    """
		Give all fertile species this player owns one population
		Void -> Void
	"""

    def fertile(self):
        fertile = self.getSpeciesWithTrait("fertile")
        for spec in fertile:
            self.species[spec].addPopulation()

    """
		Give all long-necked species this player owns one food, as long as the watering hole
		is large enough to feed them
		@param wateringHole: the dealer's watering hole
		@return the amount of food eaten by the longnecks
		Nat -> Nat
	"""

    def longNeck(self, wateringHole):
        amountFed = 0
        longNeck = self.getSpeciesWithTrait("long-neck")
        for ln in longNeck:
            if wateringHole > 0:
                fedThisSpecies = self.feedSpecies(ln, 1, wateringHole)
                amountFed += fedThisSpecies
                wateringHole -= fedThisSpecies

        return amountFed

    """
		Transfer fat food that a species stored last turn to its actual food 
		Void -> Void
	"""

    def transferFatFood(self):
        fatTissue = self.getSpeciesWithTrait("fat-tissue")
        for ft in fatTissue:
            self.species[ft].transferFatFood()

    """
		Replace a TraitCard on the given species
		@param specIdx: the index of the species whose traits need switched out
		@param oldTraitIdx: the index of the old trait card
		@param newTraitIdx: the index of the trait card replacing the old one
		Nat, Nat, Nat -> Void
	"""

    def replaceTrait(self, specIdx, oldTraitIdx, newTraitIdx):
        self.species[specIdx].replaceTrait(oldTraitIdx, self.hand[newTraitIdx])
예제 #6
0
 def __init__(self, id, bag, speciesList, cards, player=None):
     self.num = id
     self.foodbag = bag
     self.species = speciesList
     self.hand = cards
     self.player = SillyPlayer()
예제 #7
0
class Player:
  species_boards = []
  food_bag = 0
  hand = []
  player_id = 0
  externalPlayer = None

  def __init__(self, ident, loSpeciesBoard, bag, externalPlayer = None, info = None):
    """
    Initializes a player with a given id, list of species boards, and food bag
    :param ident: int
    :param loSpeciesBoard: list of Species
    :param bag: int greater than 0
    :param externalPlayer: a an extenal player (SillyPlayer or ProxyPlayer)
    :param info: String
    """
    self.species_boards = loSpeciesBoard
    self.food_bag = bag
    self.hand = []
    self.player_id = ident
    if externalPlayer:
      self.externalPlayer = externalPlayer
    else:
      self.externalPlayer = SillyPlayer(1, [], 0)
    if info:
      self.info = info
    else:
      self.info = ""

  def getInfo(self):
    """
    gets the info field in this player 
    :return: String
    """
    return self.info

  def setSpeciesBoards(self, loSpeciesBoard):
    """
    sets the list of species of this player to the given list of species
    :param loSpeciesBoard: [Species, ...]
    """
    self.species_boards = loSpeciesBoard

  def getSpeciesBoards(self):
    """
    gets the list of species of this player
    :return: [Species, ...]
    """
    return self.species_boards

  def addSpeciesBoard(self, board):
    """
    adds the species board to the player list of species
    :board: Species
    """
    self.species_boards.append(board)

  def setFoodBag(self, fb):
    """
    sets the food bag of the player to the given value
    :param fb: int
    """
    self.food_bag = fb

  def getFoodBag(self):
    """
    gets the food bag of this player
    :return: int
    """
    return self.food_bag

  def addToFoodBag(self, tokens):
    """
    adds points (tokens) to the food bag
    :param tokens: int
    """
    self.food_bag += tokens

  def setHand(self, cards):
    """
    sets the hand of the player to the given cards
    :param cards: [TraitCard, ...]
    """
    self.hand = cards

  def getHand(self):
    """
    gets the hand of the player
    :return: [TraitCard, ...]
    """
    return self.hand

  def getExternalPlayer(self):
    """
    get the external player of this internal player 
    :return: SillyPlayer or ProxyPlayer
    """
    return self.externalPlayer

  def addToHand(self, cards):
    """
    adds the given cards to this player's hand
    :param cards: [TraitCard, ...]
    """
    self.hand.extend(cards)

  def giveCard(self, i):
    """
    returns the card at the given index & deletes the card
    :param i: int that represents an index of a card in the players hand
    :return: TraitCard
    """
    if i in range(len(self.getHand())):
        card = self.getHand()[i]
    else:
	     card = self.getHand()[len(self.getHand())-1]
    return card

  def removeCardsFromHand(self, loc):
    """
    removes a the cards from this player's hand
    :param loc: [TraitCard, ...]
    :effect: modifies this player's hand
    """
    for card in loc:
      	if card in self.getHand():
      		self.getHand().remove(card)


  def setPlayerId(self, ident):
    """
    sets the id of this player to the given ident
    """
    self.player_id = ident

  def getPlayerId(self):
    """
    gets the player's id
    :return: int
    """
    return self.player_id


  def getSpeciesByIndex(self, i):
    """
    gets the species from the players list of species by index
    :param i: int
    :return: Species
    """
    return self.species_boards[i]

  def moveFatToFood(self):
    """
    Moves the fat from the fat food species to food
    """
    for animal in self.getSpeciesBoards():
      if animal.hasTrait(trait.Trait.fat_tissue):
        animal.moveFatFood()

  def removeSpeciesInLOS(self, species_index):
    """
    removes the species from the list of species in this player
    :param species: int which is the index of the species in the player species
    """
    species = self.getSpeciesByIndex(species_index)
    self.species_boards.remove(species)

  def getHungrySpeciesIndexes(self):
    """
    gets the hungry species of this player
    :return: [int, ...] which represents the indexes of the hungry species
    """
    player_species = self.getSpeciesBoards()
    hungry_species_indexes = []
    for i in range(len(player_species)):
      if player_species[i].isHungry():
        hungry_species_indexes.append(i)
    return hungry_species_indexes

  def increaseSpeciesPopulation(self, species_index, amount):
    """
    increased the population of the species at the given index
    :param species_index: int
    """
    species = self.getSpeciesByIndex(species_index)
    species.addToPopulation(amount)

  def increaseSpeciesBody(self, species_index, amount):
    """
    increased the population of the species at the given index
    :param species_index: int
    """
    species = self.getSpeciesByIndex(species_index)
    species.addToBody(amount)

  def reduceSpeciesPopulation(self, species_index, amount):
    """
    reduces the population of the species at the given index by the given ammount
    :param species_index: an int representing the index of one of this player's species
    :param amount: an int less then the population of the given species
    :return: Boolean
    """
    species = self.getSpeciesByIndex(species_index)
    return species.reducePopulation(amount)

  def starveSpecies(self):
    """
    makes the player's species have the population equal to the amount of food the species consumed
    :return: int 
    """
    deletedSpecies = 0
    for sp in self.getSpeciesBoards():
      if not sp.starve():
        self.getSpeciesBoards().remove(sp)
        deletedSpecies += 1
    return deletedSpecies

  def moveFoodToBag(self):
    """
    moves the food from the species to the player's food bag
    """
    food = 0
    for sp in self.getSpeciesBoards():
      food += sp.getFood()
      sp.setFood(0)
    self.setFoodBag(food)

  def addSpecies(self, species, bt):
    """
    Adds the traits to the given species and appends that species to the end of the species list
    :param species: a species board
    :param bt: a list of indexes corresponding to trait cards in this player's hand
    :return: [TraitCard, ...]
    """
    cards_to_discard = []
    card = self.giveCard(bt[0])
    cards_to_discard.append(card)
    for index_card in bt[1:]:
      card2 = self.giveCard(index_card)
      trait_to_add = card2.getTrait()
      species.addTrait(trait_to_add)
      cards_to_discard.append(card2)
    self.addSpeciesBoard(species)
    return cards_to_discard

  def replaceTrait(self, species_index, trait_index, card_index):
    """
    replaces the trait of the species with the given
    :param species_index: int
    :param trait_index: int
    :param card_index: int
    :return: TraitCard
    """
    species = self.getSpeciesByIndex(species_index)
    card = self.giveCard(card_index)
    trait_changed = card.getTrait()
    species.replaceTrait(trait_index, trait_changed)
    return card

  def grow(self, species_index, card_index, funct):
    """
    applies the given function on the species index
    :param species_index: int
    :param card_index: int
    :param funct: a function that takes in 2 numbers
    :return: TraitCard
    """
    card = self.giveCard(card_index)
    funct(species_index, 1)
    return card

  def apply_list(self, applylist, funct2):
    """
    adds the _ of the given species and discards the appropraite card
    :param applylist: [[String, int, int], ...]
    where the first is the index of species the second the index of the card
    :param funct2: a function that takes in  2 numbers
    :return: [TraitCard, ...]
    """

    cards_to_discard = []
    for g in applylist:
      [index_species, index_card] = g
      card = self.grow(index_species, index_card, funct2)
      cards_to_discard.append(card)

    return cards_to_discard

  def apply_rt_list(self, rt_list):
    """
    replaces the traits for the given species
    :param rt_list: [RT, ...]
    :return: [TraitCard, ...]
    """
    cards_to_discard = []
    for rt in rt_list:
      [species_index, trait_index, card_index] = rt
      card = self.replaceTrait(species_index, trait_index, card_index)
      cards_to_discard.append(card)

    return cards_to_discard

  def apply_action(self, player_action):
    """
    applies the appropriate actions
    :player_action: PlayerAction
    :return: [TraitCard, ...]
    """
    gp_list, gb_list, rt_list = player_action
    cards_to_discard = self.apply_rt_list(rt_list)
    cards_to_discard.extend(self.apply_list(gp_list, self.increaseSpeciesPopulation))
    cards_to_discard.extend(self.apply_list(gb_list, self.increaseSpeciesBody))
    return cards_to_discard

  def canFeed(self):
    """
    Checks if the call to feed follows the sequencing constraints
    throws an error if it doesn't match specs
    Returns: A boolean regarding if this player can feed a species or not
    """
    #checks if there are not enough species boards
    if (len(self.species_boards) != 0):

      #checks if there are an appropraite number of hungry animals
      hunger = False
      for animal in self.species_boards:
        if animal.getPopulation() > animal.getFood():
          hunger = True
        elif (animal.hasTrait(trait.Trait.fat_tissue)
          and (animal.getBodySize() > animal.getFatFood())):
          hunger = True

      return hunger
    return False


  def start(self, w, b, c):
    """
    add the given cards and the species board to the player and then tells the external player about the change
    :param w: int 
    :param b: Species
    :param c: [TraitCard, ...]
    """
    if b:
      self.addSpeciesBoard(b)
    self.addToHand(c)
    t = [w, self.getFoodBag(), self.getSpeciesBoards(), self.getHand()]
    self.externalPlayer.start(t)


  def choose(self, s):
    """
    queries the external player for its choice of using it's cards
    :param s: [[[Species, ...], ...], [[Species, ...], ...]]
    :return: Action4
    """
    action = self.externalPlayer.choose(s[0], s[1])
    if validate.validateAction4(action, self):
      return action
    else:
      return "delete"

  def feedNext(self, wateringHole, lolos):
    """
    queries the external player for its choice of which species to feed next
    :param wateringHole: int
    :param lop: [Player, ...] not containing this player
    :return: one of
      -False (if a player can't feed any species)
      -the index of a species in self.species_boards,
      -[the index of a species in self.species_boards with the trait fat_tissue, Nat]
      -[the index of a species in self.species_boards with the trait carnivore,
          the index of the player in the given list of players,
          and the index of an attackable species owned by the prior player]
    """
    if (not self.canFeed()):
      return None

    feedingChoice = self.externalPlayer.feedNext(wateringHole, lolos, [self.getFoodBag(), self.getSpeciesBoards(), self.getHand()])

    if validate.validateFeedingChoice(feedingChoice, self, lolos, wateringHole):
      return feedingChoice
    else:
      return "delete"


  def calculateScore(self):
    """
    calculates the score of this player
    :return: int
    """
    score = self.getFoodBag()
    for sp in self.getSpeciesBoards():
      score += sp.getPopulation()
      score += len(sp.getTraits())
    return score


  def player_strings(self):
    """
    returns the strings reperesentations of the fields in this player
    :return: [String, [String, ...], [String, ...]]
    """
    this_id = self.getPlayerId()
    this_food_bag = self.getFoodBag()
    this_hand = self.getHand()
    this_species = self.getSpeciesBoards()

    id_food_bag_string = "Player: " + "id: " + str(this_id) + ", food bag: " + str(this_food_bag)

    species_strings = []
    for species in this_species:
       species_strings.append(species.display_species())

    hand_strings = []
    if this_hand:
      for card in this_hand:
        hand_strings.append(card.display_card())

    return [id_food_bag_string, species_strings, hand_strings]

  def sortCards(self):
    sortedHand = sorted(self.getHand(), cmp = deck.compareTraitCard, reverse = True)
    return sortedHand
예제 #8
0
class PlayerState:
    num = 0
    foodbag = 0
    species = []
    hand = []
    """ 
		Internal representation of a json player
		@param num: ID number
		@param foodbag: yep
		@param species: this player's species boards
		@param hand: traitcards in this player's hand (not on boards/haven't been traded in)
		@param player: the external player with strategic functionality
		Nat, Nat, ListOf(Species), ListOf(TraitCard), Player -> PlayerState
	"""
    def __init__(self, id, bag, speciesList, cards, player=None):
        self.num = id
        self.foodbag = bag
        self.species = speciesList
        self.hand = cards
        self.player = SillyPlayer()

    """ 
		override equality
		Any -> Boolean
	"""

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        else:
            return False

    """ 
		override inequality
		Any -> Boolean
	"""

    def __ne__(self, other):
        return not self.__eq__(other)

    """
		create dictionary 
		None -> Dict
	"""

    def toDict(self):
        return {
            "num": self.num,
            "species": [species.toDict() for species in self.species],
            "hand": [card.toDict() for card in self.hand],
            "foodbag": self.foodbag
        }

    """
		Display the essence of a player
		Void -> Void
	"""

    def display(self):
        Drawing(player=self.toDict())

    """ 
	   creates a json array of a PlayerState object
	   Void -> JsonArray
	"""

    def playerStateToJson(self):
        species = [Species.speciesToJson(animal) for animal in self.species]
        cards = [TraitCard.traitCardToJson(card) for card in self.hand]

        result = [["id", self.num], ["species", species],
                  ["bag", self.foodbag]]

        if cards:
            result.append(["cards", cards])

        return result

    """
	   creates a PlayerState from a json array
	   JsonArray -> PlayerState
	"""

    @staticmethod
    def playerStateFromJson(state):
        try:
            cards = []
            if state[0][0] == "id":
                num = state[0][1]
            if state[1][0] == "species":
                speciesList = [
                    Species.speciesFromJson(species) for species in state[1][1]
                ]
            if state[2][0] == "bag":
                bag = state[2][1]
            if len(state) == 4 and state[3][0] == "cards":
                cards = [
                    TraitCard.traitCardFromJson(card) for card in state[3][1]
                ]
            if num > 0 and bag >= 0:
                return PlayerState(num, bag, speciesList, cards)

        except:
            quit()

    """
		Proxy to call the feed method in the external player
		@param wateringHole: the amount of food that can be eaten
		@param players: all the players in this round
		@return FeedingAction -One of:
			False - no feeding at this time
			Nat - index of Species fed
			[Nat, Nat] - index of fat-tissue Species fed, amount of fatFood
			[Nat, Nat, Nat] - index of carnivore, index of player to attack, index of species to attack
		Nat, ListOf(PlayerState) -> FeedingAction
	"""

    def feed(self, wateringHole, player):
        return self.player.feed(self, wateringHole, player)

    """
		Filter out all fed species to get a list of species that can be fed
		@return a list of (Species' index, Species) for hungry species this player has
		Void -> ListOf((Nat, Species))
	"""

    def getHungrySpecies(self):
        hungry = []
        for i in range(len(self.species)):
            if self.species[i].isHungry():
                hungry.append((i, self.species[i]))

        return hungry

    """
		Gets the indexes of the species neighboring the given species
		@param speciesIdx: index of the species to get neighbors for
		Nat -> [OptSpecies, OptSpecies] where an OptSpecies is Species or False
	"""

    def getNeighbors(self, speciesIdx):
        if speciesIdx > 0:
            lNeighbor = self.species[speciesIdx - 1]
        else:
            lNeighbor = False

        if speciesIdx < len(self.species) - 1:
            rNeighbor = self.species[speciesIdx + 1]
        else:
            rNeighbor = False

        return [lNeighbor, rNeighbor]

    """
		Verify that this player can use their own chosen species to attack the other given species
		@param defPlayer: PlayerState of the defending player
		@param defIdx: index of the defending species
		@param attIdx: index of the attacking species: should be one of our own
		PlayerState, Nat, Nat -> Boolean
	"""

    def verifyAttack(self, defPlayer, attIdx, defIdx):
        left, right = defPlayer.getNeighbors(defIdx)
        return Species.isAttackable(defPlayer.species[defIdx],
                                    self.species[attIdx], left, right)

    """
		Tell whether or not the given species is extinct (i.e. that its population <= 0)
		@param specIdx: index of the species to check
		Nat -> Boolean
	"""

    def isExtinct(self, specIdx):
        return self.species[specIdx].isExtinct()

    """
		Remove the given species from this player's list of species
		@param specIdx: index of the species to remove
		Nat -> Void
	"""

    def removeSpecies(self, specIdx):
        del self.species[specIdx]

    """
		Tell whether or not this player has any species
		Void -> Boolean
	"""

    def hasNoSpecies(self):
        return not (len(self.species) > 0)

    """
		Tell whether the species at the given index has the given trait
		@param specIdx: the index of the species to check
		@param traitName: the name of the trait to check for
		Nat, String -> Boolean
	"""

    def speciesHasTrait(self, specIdx, traitName):
        return self.species[specIdx].hasTrait(traitName)

    """
		Drop the population of the given species as in a carnivore attack
		If the species' food > its population, drop the food as well
		@param specIdx: the index of the species to have its population decremented
		Nat -> Void
	"""

    def executeAttack(self, specIdx):
        self.species[specIdx].executeAttack()

    """
		Feed the given species the given amount of fat food that it requested
		@param specIdx: index of the species to feed
		@param foodCount: amount of food to try to feed
		@return the amount of food this species was given
		Nat, Nat -> Nat
	"""

    def feedFatFood(self, specIdx, foodCount):
        spec = self.species[specIdx]
        if spec.hasTrait("fat-tissue"):
            foodCount = min(foodCount, spec.body - spec.fatFood)
            spec.eatFatFood(foodCount)
            return foodCount
        else:
            raise ValueError(
                "Tried to feed fat food to a species without fat tissue")

    """
		Feed a given species the amount of food that it requested
		@param specIdx: index of the species to feed
		@param foodCount: amount of food to try to feed
		@param wateringHole: the amount of food in the dealer's watering hole
		@return the total amount of food eaten during this feeding
		Nat, Nat, Nat -> Nat
	"""

    def feedSpecies(self, specIdx, foodCount, wateringHole):
        spec = self.species[specIdx]
        foodCount = min(wateringHole, foodCount, spec.population - spec.food)
        spec.eatFood(foodCount)
        wateringHole -= foodCount

        forageAmount = self.forage(specIdx, wateringHole)
        wateringHole -= forageAmount
        foodCount += forageAmount

        foodCount += self.cooperate(specIdx, foodCount, wateringHole)

        return foodCount

    """
		If the given species has the foraging trait, give it one more food
		@param specIdx: index of the species to feed
		@param wateringHole: the amount of food in the dealer's watering hole
		@return the amount of food this species ate
	"""

    def forage(self, specIdx, wateringHole):
        spec = self.species[specIdx]
        amountFed = 0
        if wateringHole > 0 and spec.hasTrait(
                "foraging") and spec.population > spec.food:
            spec.eatFood(1)
            amountFed += 1

        return amountFed

    """
		Cooperate
		@param specIdx: index of the species to feed
		@param foodCount: amount of food to try to feed
		@param wateringHole: the amount of food in the dealer's watering hole
		@return the amount of food all species in the cooperation chain ate
		Nat, Nat, Nat -> Nat
	"""

    def cooperate(self, specIdx, foodCount, wateringHole):
        spec = self.species[specIdx]
        amountFed = 0
        left, right = self.getNeighbors(specIdx)
        if spec.hasTrait("cooperation") and right is not False:
            for i in range(foodCount):
                if wateringHole > 0:
                    fedThisSpecies = self.feedSpecies(specIdx + 1, 1,
                                                      wateringHole)
                    amountFed += fedThisSpecies
                    wateringHole -= fedThisSpecies

        return amountFed

    """
		After a carnivore attack, have all species with the scavenge trait eat from left to right
		@param wateringHole: the amount of food that can be handed out amongst the scavengers
		@return the amount of food eaten amongst our scavengers
		Nat -> Nat
	"""

    def scavenge(self, wateringHole):
        amountFed = 0
        for i in range(len(self.species)):
            if self.speciesHasTrait(i, "scavenger"):
                fedThisSpecies = self.feedSpecies(i, 1, wateringHole)
                amountFed += fedThisSpecies
                wateringHole -= fedThisSpecies

        return amountFed
예제 #9
0
class TestStrategy(unittest.TestCase):
  def setUp(self):
    self.player = SillyPlayer(1, [], 0)
    self.strat = strategy.Strategy()

    self.carnivore = species.Species(0, 1, 1, [])
    self.carnivore.setTraits([trait.Trait.carnivore])
    self.fat_carnivore = species.Species(0, 1, 1, [])
    self.fat_carnivore.setTraits([trait.Trait.carnivore])
    self.fat_carnivore.setBodySize(5)

    self.herbavore = species.Species(0, 1, 1, [])
    self.fat_herbavore = species.Species(0, 1, 1, [])
    self.fat_herbavore.setBodySize(4)

    self.fat_tissue = species.Species(0, 1, 1, [])
    self.fat_tissue.setBodySize(3)
    self.fat_tissue.setTraits([trait.Trait.fat_tissue])
    self.fat_fat_tissue = species.Species(0, 1, 1, [])
    self.fat_fat_tissue.setBodySize(6)
    self.fat_fat_tissue.setTraits([trait.Trait.fat_tissue])

    self.opherb = species.Species(0, 1, 1, [])
    self.opfatherb = species.Species(0, 1, 1, [])
    self.opfatherb.setBodySize(4)

    self.opponent1 = SillyPlayer(1, [], 0)
    self.opponent1.setSpeciesBoards([self.opherb, self.opfatherb])
    self.opponents = [[self.opherb, self.opfatherb]]

    self.dealer = dealer.Dealer(4, [self.player, self.opponent1])

  def tearDown(self):
    del self.player
    del self.carnivore
    del self.herbavore
    del self.fat_tissue
    del self.opherb
    del self.opfatherb
    del self.opponent1
    del self.opponents
    del self.dealer

  def testFatTissueFirst(self):
    self.player.setSpeciesBoards([self.herbavore, self.fat_tissue])
    self.assertEqual(self.player.feedNext(4, self.opponents, [self.player.getFoodBag(), self.player.getHand(), self.player.getSpeciesBoards()]), [1, 3])

  def testBiggestFatTissueFirst(self):
    self.player.setSpeciesBoards([self.fat_tissue, self.fat_fat_tissue])
    self.assertEqual(self.player.feedNext(4, self.opponents, [self.player.getFoodBag(), self.player.getHand(), self.player.getSpeciesBoards()]), [1, 4])

  def testHerbBeforeCarni(self):
    self.player.setSpeciesBoards([self.herbavore, self.carnivore])
    self.assertEqual(self.player.feedNext(4, self.opponents, [self.player.getFoodBag(), self.player.getHand(), self.player.getSpeciesBoards()]), 0)

  def testLargestHerbFirst(self):
    self.player.setSpeciesBoards([self.herbavore, self.fat_herbavore])
    self.assertEqual(self.player.feedNext(4, self.opponents, [self.player.getFoodBag(), self.player.getHand(), self.player.getSpeciesBoards()]), 1)

  def testLargestCarnivoreFirstIfAllHerbFed(self):
    self.herbavore.setFood(1)
    self.player.setSpeciesBoards([self.herbavore, self.carnivore, self.fat_carnivore])
    self.assertEqual(self.player.feedNext(4, self.opponents, [self.player.getFoodBag(), self.player.getHand(), self.player.getSpeciesBoards()]), [2, 0, 1])

  def testWontAttackSelf(self):
    self.player.setSpeciesBoards([self.fat_carnivore])
    self.opponents = []
    self.assertEqual(self.player.feedNext(4, self.opponents, [self.player.getFoodBag(), self.player.getHand(), self.player.getSpeciesBoards()]), False)

  # #Unit Test Helper Methods
  def testSortByLexPop(self):
    self.herbavore.setPopulation(1)
    self.carnivore.setPopulation(3)
    loa = [self.herbavore, self.carnivore]
    self.assertEqual(self.strat.sortByLex(loa, False), [self.carnivore, self.herbavore])

  def testSortByLexFood(self):
    self.herbavore.setPopulation(1)
    self.carnivore.setPopulation(1)
    self.herbavore.setFood(1)
    self.carnivore.setFood(3)
    loa = [self.carnivore, self.herbavore]
    self.assertEqual(self.strat.sortByLex(loa, False), [self.carnivore, self.herbavore])

  def testSortByLexBodySize(self):
    self.herbavore.setPopulation(1)
    self.carnivore.setPopulation(1)
    self.herbavore.setFood(1)
    self.carnivore.setFood(1)
    self.herbavore.setBodySize(1)
    self.carnivore.setBodySize(3)
    loa = [self.carnivore, self.herbavore]
    self.assertEqual(self.strat.sortByLex(loa, False), [self.carnivore, self.herbavore])

  def testSortByLex(self):
    self.herbavore.setPopulation(1)
    self.herbavore.setFood(1)
    self.herbavore.setBodySize(3)

    self.carnivore.setPopulation(2)
    self.carnivore.setFood(1)
    self.carnivore.setBodySize(2)

    self.fat_tissue.setPopulation(1)
    self.fat_tissue.setFood(2)
    self.fat_tissue.setBodySize(3)

    loa = [self.herbavore, self.carnivore, self.fat_tissue]
    loas = self.strat.sortByLex(loa, False)
    self.assertEqual(loas, [self.carnivore, self.fat_tissue, self.herbavore])

  def testStereotypeAnimals(self):
    loa = [self.fat_herbavore, self.herbavore, self.fat_carnivore, self.fat_tissue]
    expectedOutput = ([self.fat_tissue], [self.fat_carnivore], [self.fat_herbavore, self.herbavore])
    self.assertEqual(self.strat.stereotypeAnimals(loa), expectedOutput)

  def testFindFattestIfFatTissue(self):
    fat = [self.fat_tissue]
    carni = [self.fat_carnivore]
    herb = [self.fat_herbavore, self.herbavore]
    self.assertEqual(self.strat.findFattest(fat, carni, herb), (self.fat_tissue, trait.Trait.fat_tissue))

  def testFindFattestIfHerbi(self):
    fat = []
    carni = [self.fat_carnivore]
    herb = [self.fat_herbavore, self.herbavore]
    self.assertEqual(self.strat.findFattest(fat, carni, herb), (self.fat_herbavore, False))

  def testFindFattestIfCarni(self):
    fat = []
    carni = [self.fat_carnivore]
    herb = []
    self.assertEqual(self.strat.findFattest(fat, carni, herb), (self.fat_carnivore, trait.Trait.carnivore))

  def testFeedNext(self):
    loa = [self.fat_herbavore, self.herbavore, self.fat_carnivore, self.fat_tissue]
    self.assertEqual(self.strat.feedNext(loa), (self.fat_tissue, trait.Trait.fat_tissue))


  def testSortOpponentsSpecies(self):
    inpt = [[self.herbavore, self.fat_tissue], [self.opherb, self.opfatherb]]
    output = [[self.fat_tissue, self.herbavore] , [self.opfatherb, self.opherb]]
    self.assertEqual(self.strat.sortOpponentsSpecies(inpt), output)

  def testGetNeighborsNoLeft(self):
    self.assertEqual(self.strat.getNeighbors([self.herbavore, self.fat_tissue], self.fat_tissue), (self.herbavore, False))

  def testGetNeighborsNoRight(self):
    self.assertEqual(self.strat.getNeighbors([self.herbavore, self.fat_tissue], self.herbavore), (False, self.fat_tissue))

  def testPickVictim(self):
    self.assertEqual(self.strat.pickVictim([self.carnivore], [[self.herbavore, self.fat_tissue], [self.opherb, self.opfatherb]]), [1, 1 , self.carnivore])
예제 #10
0
    def setUp(self):
        self.t1 = TraitCard("horns", 3)
        self.t2 = TraitCard("ambush", 1)
        self.t3 = TraitCard("carnivore", 2)
        self.t4 = TraitCard("fat-tissue", 0)
        self.t5 = TraitCard("foraging", 3)
        self.vegHorns = Species(1, 2, 3, [TraitCard("horns")], 0)
        self.vegCoop = Species(1, 2, 3, [TraitCard("cooperation")], 0)
        self.fat = Species(4, 3, 4, [TraitCard("fat-tissue")], 3)
        self.fatScav = Species(
            2, 3, 4, [TraitCard("fat-tissue"),
                      TraitCard("scavenger")], 1)
        self.fatFor = Species(4, 3, 4,
                              [TraitCard("fat-tissue"),
                               TraitCard("foraging")], 1)
        self.carnCoop = Species(
            3, 4, 5, [TraitCard("carnivore"),
                      TraitCard("cooperation")], 0)
        self.carnForage = Species(
            3, 4, 5, [TraitCard("carnivore"),
                      TraitCard("foraging")], 0)
        self.carnForage1 = Species(
            3, 4, 5, [TraitCard("carnivore"),
                      TraitCard("foraging")], 0)
        self.extinct = Species(0, 0, 0, [], 0)
        self.p1 = PlayerState(1, 0, [self.vegCoop, self.fat, self.carnForage],
                              [], SillyPlayer())
        self.p2 = PlayerState(2, 0,
                              [self.vegHorns, self.fatScav, self.carnCoop], [],
                              SillyPlayer())
        self.p3 = PlayerState(3, 0,
                              [self.vegCoop, self.carnCoop, self.carnForage1],
                              [], SillyPlayer())
        self.p4 = PlayerState(4, 0, [self.vegCoop], [])
        self.p5 = PlayerState(5, 0, [self.vegHorns], [])
        self.p6 = PlayerState(6, 0, [self.carnCoop], [])
        self.p7 = PlayerState(7, 0, [self.fatScav], [])
        self.p8 = PlayerState(8, 0, [self.fatFor, self.extinct], [])
        self.dealer = Dealer([self.p1, self.p2, self.p3], 3,
                             [self.t1, self.t2, self.t3, self.t4, self.t5])
        self.p2dealer = Dealer([self.p6, self.p5], 3, [])
        self.p3dealer = Dealer([self.p8], 3,
                               [self.t1, self.t2, self.t3, self.t4, self.t5])

        self.xstep3spec = Species(0, 5, 2, [TraitCard("foraging")], 0)
        self.xstep3p = PlayerState(1, 0, [self.xstep3spec], [])
        self.xstep3deal = Dealer([self.xstep3p], 5, [])

        # 8949-0357-4
        self.pCFS1 = PlayerState(1, 3, [
            Species(4, 2, 5,
                    [TraitCard("carnivore"),
                     TraitCard("cooperation")], 0),
            Species(1, 3, 4, [
                TraitCard("foraging"),
                TraitCard("carnivore"),
                TraitCard("scavenger")
            ], 0)
        ], [])
        self.pCFS2 = PlayerState(
            2, 4, [Species(2, 3, 3, [TraitCard("burrowing")], 0)], [])
        self.pCFS3 = PlayerState(3, 5, [], [])
        self.dCFS = Dealer([self.pCFS1, self.pCFS2, self.pCFS3], 10, [])

        # for step4
        self.t6 = TraitCard("herding", 0)
        self.defSpec = Species(0, 0, 1, [], 0)
        self.specWGrownBody = Species(0, 1, 1, [], 0)
        self.specW3t = Species(0, 0, 1, [self.t3, self.t4, self.t5], 0)
        self.specWAll = Species(2, 1, 2, [self.t4], 1)
        self.playerWithManyCards = PlayerState(
            1, 0, [], [self.t1, self.t2, self.t3, self.t4, self.t5, self.t6])
        self.playerForAll = PlayerState(1, 0, [self.specWAll], [])
        self.playerFor3t = PlayerState(1, 0, [self.specW3t], [self.t6])
        self.playerForDefSpec = PlayerState(1, 0, [self.defSpec],
                                            [self.t5, self.t6])
        self.playerForBodyNewSpec = PlayerState(
            1, 0, [self.specWGrownBody], [self.t3, self.t4, self.t5, self.t6])
        self.noAct = Action4(0, [], [], [], [])
        self.actGP = Action4(0, [GainPopulation(0, 0)], [], [], [])
        self.actGB = Action4(0, [], [GainBodySize(0, 1)], [], [])
        self.actRT = Action4(0, [], [], [], [ReplaceTrait(0, 1, 1)])
        self.actBT0t = Action4(0, [], [], [BuySpeciesBoard(1, [])], [])
        self.actBT1t = Action4(0, [], [], [BuySpeciesBoard(1, [2])], [])
        self.actBT2t = Action4(0, [], [], [BuySpeciesBoard(1, [2, 3])], [])
        self.actBT3t = Action4(0, [], [], [BuySpeciesBoard(1, [2, 3, 4])], [])
        self.actBT4t = Action4(0, [], [], [BuySpeciesBoard(1, [2, 3, 4, 5])],
                               [])
        self.addBodyToNewSpec = Action4(0, [GainPopulation(1, 1)], [],
                                        [BuySpeciesBoard(2, [3])], [])
        self.actAll = Action4(0, [GainPopulation(0, 1)], [GainBodySize(0, 2)],
                              [BuySpeciesBoard(4, [5])],
                              [ReplaceTrait(0, 0, 3)])
        self.simpleDealerForStep4 = Dealer([self.playerWithManyCards], 0, [])
        self.dealerForRevokingCards = Dealer([
            PlayerState(1, 0, [], [self.t1, self.t2]),
            PlayerState(2, 0, [], [self.t3, self.t4, self.t5]),
            PlayerState(3, 0, [], [self.t6])
        ], 0, [])

        self.dealerManyActions = Dealer([
            PlayerState(1, 0, [self.defSpec], [self.t1, self.t2]),
            PlayerState(2, 0, [self.vegHorns, self.fatScav, self.carnCoop],
                        [self.t3, self.t4, self.t5, self.t6, self.t1]),
            PlayerState(3, 0, [self.vegCoop, self.carnCoop, self.carnForage1],
                        [self.t6])
        ], 0, [])
예제 #11
0
 def new(self, pid):
   """
   add a player to this proxyDealer
   :param pid: int
   """
   self.externalPlayer = SillyPlayer(pid, [], 0)
예제 #12
0
class ProxyDealer:
  def __init__(self):
    self.sock = None
    #self.streamer = xstream.EchoStream()
    self.proxyPlayer = None
    self.externalPlayer = None
    # SillyPlayer(9, [], 0)
    self.gotOK = False

  def receiveData(self):
    data = None
    try:
        data = self.sock.recv(SIZE)
        return data
    except socket.error:
        return data

  def disconnect(self):
    self.sock.close()

  def getExternalPlayer(self):
    return self.externalPlayer

  def signUp(self, s):
    """
    send a massage to the server in order to join the game
    :param s: String
    """
    self.sock.sendall(json.dumps(s))


  def new(self, pid):
    """
    add a player to this proxyDealer
    :param pid: int
    """
    self.externalPlayer = SillyPlayer(pid, [], 0)


  def start(self, s):
    """
    intializes the externalPlayer
    :param s: [int, int, [Species_j+, ...], [SpeciesCard, ...]]
    :effect: calls the start method of the external player
    """
    t = parse_json.parse_s(s)
    self.externalPlayer.start(t)
    # self.sock.sendall(json.dumps("ok"))

  def choose(self, cdj):
    """
    asks the external player how it chooses the cards
    :param cdj: [[[Species_j+, ...], ...], [[Species_j+, ...], ...]]
    :effect: calls the choose method of the external player
    :return: Action4
    """
    c, d = parse_json.parse_cdj(cdj)
    action4 = self.externalPlayer.choose(c, d)
    self.sock.sendall(json.dumps(action4))

  def feedNext(self, zs):
    """
    asks the external player what species to feed next
    :param zs: [int, [Species_j+, ...], [SpeciesCard, ...], int, [[Species_j, ...], ...]]
    :effect: calls the feedNext method in the external player
    :return: FeedingChoice
    """
    ys = parse_json.parse_state(zs)
    feeding = self.externalPlayer.feedNext(ys[0], ys[1], ys[2])
    self.sock.sendall(json.dumps(feeding))

  def callMethod(self, data):
    """
    calls the correct method based on the received data
    :param data: List
    """
    if ((data == "ok") and (not self.gotOK)):
        self.gotOk = True

    elif self.gotOk:
        if (not isinstance(data, list) and (data != "ok")):
            self.new(data)
        elif len(data) == 2:
            self.choose(data)
        elif len(data) == 4:
            self.start(data)
        elif len(data) == 5:
            self.feedNext(data)
        else:
            self.disconnect()
    else:
        self.disconnect()


  def main(self):
    """
    Setup and manage TCP connection to game server; deliver messages as Python
    objects to the appropriate player proxy method, return their responses (as JSON)
    to the game server.
    """
    try:
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    except socket.error as msg:
        raise Exception('Socket error {} : {}'.format(msg[0], msg[1]))
    try:
        self.sock.connect((HOST, PORT))
    except socket.error as msg:
        raise Exception('Socket error {} : {}'.format(msg[0], msg[1]))

    self.signUp("Pikachu")

    while True:
        data = self.receiveData()
        if data:
            try:
                d = json.loads(data)
                self.callMethod(d)
            except ValueError:
                self.disconnect()

    self.disconnect()