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
endTo 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),
p -> NewRobotPlayer(p))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})::FunctionGiven 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 Tuple 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...)::PlayerPublicViewThe 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, players::AbstractVector{PlayerPublicView}, player::RobotPlayer)::SymbolReturned 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)::SymbolCalled 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)::SymbolCalled 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})::BoolDecides 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})::SymbolCalled 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 <: PlayerTypePerform 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 <: PlayerTypePerform 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.