Configuration of a new player
Catan.jl
allows for full customizability of scripted players using Julia's Type framework. This is done by defining a new struct and implementing any methods for which you wish to add custom behavior, as detailed below.
For more advanced usage, see CatanLearning.jl.
Setting up the type
Define a new player called NewRobotPlayer
requires the definition of a mutable struct
inheriting from abstract type RobotPlayer
,
mutable struct NewRobotPlayer <: RobotPlayer
player::Player
# Here, Insert any other fields to store intermediary data or parameters during game
end
To let it interact with the Catan.jl
framework, it must have a constructor accepting (team::Symbol, configs::Dict)
, and it must be registered. Continuing with our above example,
NewRobotPlayer(team::Symbol, configs::Dict) = NewRobotPlayer(Player(team, configs))
Catan.add_player_to_register("New Robot Player Experiment", (t,c) -> NewRobotPlayer(t,c))
and now it can be used in gameplay by configuring the player in the configuration TOML file,
...
[PlayerSettings]
[PlayerSettings.blue]
TYPE = "New Robot Player Experiment"
[PlayerSettings.cyan]
TYPE = "DefaultRobotPlayer"
[PlayerSettings.green]
TYPE = "DefaultRobotPlayer"
[PlayerSettings.yellow]
TYPE = "DefaultRobotPlayer"
...
Methods for defining custom player behavior
An exhaustive list of methods that can be implemented to override the default behavior (uniform random) of the DefaultRobotPlayer
, ordered roughly in order of descending importance for gameplay.
High-level decisions
Catan.choose_next_action
— Functionchoose_next_action(board::Board, players::AbstractVector{PlayerPublicView}, player::RobotPlayer,
actions::Set{PreAction})::Function
Given a Set
of PreAction
legal move categories, decide what will be taken as the next action. The return Function
needs to accept a Game, Board, PlayerType
triple.
TODO integrate with CatanLearning
Action
type. This should not be returning a function.
Construction
Catan.choose_building_location
— Functionchoose_building_location(board::Board, players::AbstractVector{PlayerPublicView},
player::RobotPlayer, candidates::Vector{Tuple{Int, Int}}, building_type::Symbol
)::Tuple{Int,Int}
candidates
is guaranteed to be non-empty. This method is only called if there is a legal placement available.
Catan.choose_road_location
— Functionchoose_road_location(board::Board, players::AbstractVector{PlayerPublicView},
player::RobotPlayer, candidates::Vector{Vector{Tuple{Int, Int}}})
::Vector{Tuple{Int, Int}}
candidates
is guaranteed to be non-empty. Given all legal road placements, return a Vector
containing two coordinates signifying the road placement choice.
Robbers and knights
Catan.choose_place_robber
— Functionchoose_place_robber(board::Board, players::AbstractVector{PlayerPublicView}, player::RobotPlayer,
candidates::Vector{Symbol})::Union{Nothing, Symbol}
Catan.choose_robber_victim
— Functionchoose_robber_victim(board::Board, player::RobotPlayer,
potential_victims::PlayerPublicView...)::PlayerPublicView
The robber has already been placed, so here player
decided which adjacent player to steal from.
Catan.choose_one_resource_to_discard
— Functionchoose_one_resource_to_discard(board::Board, player::RobotPlayer)::Symbol
Returned symbol must be present in both Catan.RESOURCES
and keys(player.resources)
.
Development cards
Catan.choose_resource_to_draw
— Functionchoose_resource_to_draw(board, players::AbstractVector{PlayerPublicView},
player::RobotPlayer)::Symbol
Called two times during the Year of Plenty development card action. TODO inconsistent naming.
Catan.choose_monopoly_resource
— Functionchoose_monopoly_resource(board::Board, players::AbstractVector{PlayerPublicView},
player::RobotPlayer)::Symbol
Called during the Monopoly development card action. Choose the resource to steal from each player based on public information.
Trading
Catan.choose_accept_trade
— Functionchoose_accept_trade(board::Board, player::RobotPlayer, from_player::PlayerPublicView,
from_goods::Vector{Symbol}, to_goods::Vector{Symbol})::Bool
Decides whether player
will accept the trade from from_player
. The trade is not performed within this function.
Catan.choose_who_to_trade_with
— Functionchoose_who_to_trade_with(board::Board, player::RobotPlayer,
players::AbstractVector{PlayerPublicView})::Symbol
Called when multiple other players have accepted a trade offer via choose_accept_trade
, and now the trade initiator, player
, selects which player will be selected.
Optimization and data generation
Catan.initialize_player
— Functioninitialize_player(board::Board, player::PlayerType)
This function is useful to do any one-time computations of the player as soon as the board is generated.
Catan.do_post_game_action
— Functiondo_post_game_action(game::Game, board::Board, players::AbstractVector{T}, player::T,
winner::Union{PlayerType, Nothing}) where T <: PlayerType
Perform any post-game actions while the full Game
and Board
states are in memory, and the winner
has been defined. Feature generation is one example. See CatanLearning.jl for usage.
do_post_game_action(game::Game, board::Board, players::AbstractVector{T},
winner::Union{PlayerType, Nothing}) where T <: PlayerType
Perform any post-game actions while the full Game
and Board
states are in memory, and the winner
has been defined. Feature generation is one example. See CatanLearning.jl for usage.