GameTheory.jl
GameTheory.jl copied to clipboard
payoff_function instead of payoff_array?
As @StefanKarpinski told me:
It may be better to represent a player's payoff function by a function, "payoff_function
" or "payoff_func
, instead of array payoff_array
.
It sounds a great idea to me now.
What would this look like?
This is a terrible implementation and we could certainly do much better, but would this be the type of thing you had in mind:
abstract AbstractPlayer
abstract AbstractNFG
immutable MPPlayer1 <: AbstractPlayer end
immutable MPPlayer2 <: AbstractPlayer end
Base.call(::MPPlayer1, me::Int, them::Int) = me == them ? 1 : -1
Base.call(::MPPlayer2, me::Int, them::Int) = me == them ? -1 : 1
immutable MatchingPennies <: AbstractNFG
p1:: MPPlayer1
p2:: MPPlayer2
end
mp1 = MPPlayer1()
mp2 = MPPlayer2()
g = MatchingPennies(mp1, mp2)
mp1(1, 1) # == 1
mp1(1, 2) # == -1
mp2(1, 1) # == -1
mp2(1, 2) # == 1
I am not sure... I was naively thinking about something like:
type Player
payoff_function::Function
end
u_1(me::Integer, them::Integer) = me == them ? 1 : -1
function u_2(me::Integer, them::Integer)
payoff_matrix = [-1 1; 1 -1] # Can be defined by a payoff array
return payoff_matrix[me, them]
end
p1 = Player(u_1)
p2 = Player(u_2)
@StefanKarpinski what's the latest with having fields of type Function
in a type?
I've always avoided it and relied on dispatch, but with new function changes maybe we don't need to do that anymore?
It should be faster now in some cases but not all cases. One thing I believe you can do is make the function a type parameter and then we will get code specialized for specific payoff functions, which could be very fast but may be overkill. Another thing we can do is just put the right type assertions in the places where we call the functions – since we know what these functions should return. In fact, we could have a nominal PayoffFunction
type that is callable but has type assertions on the return of its call method(s).