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_actionFunction
choose_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.

source

Construction

Catan.choose_building_locationFunction
choose_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.

source
Catan.choose_road_locationFunction
choose_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.

source

Robbers and knights

Catan.choose_place_robberFunction
choose_place_robber(board::Board, players::AbstractVector{PlayerPublicView}, player::RobotPlayer, 
candidates::Vector{Symbol})::Union{Nothing, Symbol}
source
Catan.choose_robber_victimFunction
choose_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.

source
Catan.choose_one_resource_to_discardFunction
choose_one_resource_to_discard(board::Board, player::RobotPlayer)::Symbol

Returned symbol must be present in both Catan.RESOURCES and keys(player.resources).

source

Development cards

Catan.choose_resource_to_drawFunction
choose_resource_to_draw(board, players::AbstractVector{PlayerPublicView}, 
player::RobotPlayer)::Symbol

Called two times during the Year of Plenty development card action. TODO inconsistent naming.

source
Catan.choose_monopoly_resourceFunction
choose_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.

source

Trading

Catan.choose_accept_tradeFunction
choose_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.

source
Catan.choose_who_to_trade_withFunction
choose_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.

source

Optimization and data generation

Catan.initialize_playerFunction
initialize_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.

source
Catan.do_post_game_actionFunction
do_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.

source
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.

source