# Copyright (c) 2019-2021 Elias Fernandez## This file is part of EGTtools.## EGTtools is free software: you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation, either version 3 of the License, or# (at your option) any later version.## EGTtools is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with EGTtools. If not, see <http://www.gnu.org/licenses/>fromtypingimportList,Unionimportnumpyasnpfrom..import(sample_simplex,)from.importAbstractNPlayerGamefrom..behaviors.pgg_behaviorsimportPGGOneShotStrategy
[docs]def__init__(self,group_size:int,cost:float,multiplying_factor:float,strategies:List[PGGOneShotStrategy])->None:""" Classical Public Goods game with only 2 possible contributions (o or cost). Parameters ---------- group_size: int Size of the group playing the game. cost: float Cost of cooperation. multiplying_factor: float The sum of contributions to the public good is multiplied by this factor before being divided equally among all players. strategies: List[egttools.behaviors.pgg_behaviors.PGGOneShotStrategy] A list of strategies that will play the game. """AbstractNPlayerGame.__init__(self,len(strategies),group_size)self.group_size_=group_sizeself.c_=costself.r_=multiplying_factorself.strategies_=strategiesself.nb_strategies_=len(strategies)self.nb_group_configurations_=self.nb_group_configurations()self.calculate_payoffs()
[docs]defcalculate_payoffs(self)->np.ndarray:payoffs_container=np.zeros(shape=(self.nb_strategies_,),dtype=np.float64)foriinrange(self.nb_group_configurations_):# Get group compositiongroup_composition=sample_simplex(i,self.group_size_,self.nb_strategies_)self.play(group_composition,payoffs_container)forstrategy_index,strategy_payoffinenumerate(payoffs_container):self.update_payoff(strategy_index,i,strategy_payoff)# Reinitialize payoff vectorpayoffs_container[:]=0returnself.payoffs()
[docs]def__str__(self)->str:string=f''' Python implementation of a public goods game.\n Game parameters ------- cost = {self.c_}\n multiplication_factor = {self.r_}\n Strategies ------- nb_strategies = {self.nb_strategies_}\n strategies = {self.strategies_}\n '''returnstring
[docs]defsave_payoffs(self,file_name:str)->None:withopen(file_name,'w')asf:f.write('Payoffs for each type of player and each possible state:\n')f.write(f'rows: {" ,".join([strategy.typeforstrategyinself.strategies_])}\n')f.write('cols: all possible group compositions starting at (0, 0, ..., group_size)\n')f.write(f'{self.payoffs_}')f.write(f'group_size = {self.group_size_}\n')f.write(f'cost = {self.c_}\n')f.write(f'multiplying_factor = {self.r_}\n')