Public API
Index
GridSim.count_valuesGridSim.daysGridSim.endless_daysGridSim.enlargeGridSim.enlarge!GridSim.firstdayGridSim.game_rngGridSim.gamerulesGridSim.grid_indexesGridSim.gridsizeGridSim.most_commonGridSim.most_commonsGridSim.newgameGridSim.nextday!GridSim.rulesGridSim.seedof
Game rules
GridSim.gamerules — Functiongamerules(grid_size::Tuple{Int,Int}, cellfunc::Union{Function,Symbol,String}; rng=nothing)Create a GameRules object, given the grid size, the cell function and an optional random number generator or seed.
Arguments
grid_size: the size of the gridcellfunc: the function that will be used to determine the next value of each cell. It must take the following arguments in the same order :::AbstractMatrix: the matrix of the day::Tuple{Int,Int}: the size of the grid (i.e.size(M))::Int: the row index of the cell::Int: the column index of the cell
Keywords (optional)
rng::Union{AbstractRNG,Integer} : the random number generator to use. If passed a seed (an integer), it will create the default julia algorithmic random number generator (Xoshiro) with this seed. If not provided, it will generate a random seed.
Example
julia> function cellfunc(M, grid_size, i, j)
# Return the cell value and the value of the cell above
# (if it exists)
i == 1 && return [M[i, j]]
return [M[i, j], M[i-1, j]]
end
cellfunc (generic function with 1 method)
julia> gamerules((4, 4), cellfunc, rng=1)
GridSim.GameRules((4, 4), cellfunc, Random.Xoshiro(0xfff0241072ddab67, 0xc53bc12f4c3f0b4e, 0x56d451780b2dd4ba, 0x50a4aa153d208dd8, 0x3649a58b3b63d5db), 1)This package already implements three rules:
neigh_disk: Selects the neighbors of the value, edges are not linkedneigh_cylinder: Selects the neighbors of the value, only bottom and top are linkedneigh_torus: Selects the neighbors of the value, all edges are linked
Game creation
GridSim.newgame — Functionnewgame(first_day::AbstractMatrix, rules::GameRules)
newgame(first_day::AbstractMatrix, cellfunc::Function, fill::Type; rng=nothing)
newgame(grid_size::Tuple{Int,Int}, territory_size::Tuple{Int,Int}, cellfunc::Function, fill::Type; rng=nothing)Create a Game object with the specified first day matrix and the rules. These two arguments can be automatically created with the firstday and gamerules functions, respectively. Or you can pass the arguments directly into the constructor. See the documentation of these two functions for more details.
Example
julia> game = newgame((4, 4), (2, 2), neigh_disk, Int, rng=1)
GridSim.Game{Matrix{Int64}}([1 1 2 2; 1 1 2 2; 3 3 4 4; 3 3 4 4], GridSim.GameRules((4, 4), neigh_disk, Random.Xoshiro(0xfff0241072ddab67, 0xc53bc12f4c3f0b4e, 0x56d451780b2dd4ba, 0x50a4aa153d208dd8, 0x3649a58b3b63d5db), 1))Game iteration
GridSim.nextday! — Functionnextday!(game, oldday, newday)Compute the next game day in the newday matrix (inplace), based on the oldday matrix that is the day just before.
Example
julia> game = newgame((4, 4), (2, 2), neigh_disk, Int, rng=1);
julia> new_day = similar(firstday(game));
julia> nextday!(game, firstday(game), new_day)
julia> new_day
4×4 Matrix{Int64}:
1 2 2 2
1 1 2 2
3 3 4 4
3 3 4 4GridSim.days — Functiondays(game::Game[,maxdays]; stop_check=1, copydays=true)Return an iterator over the days of the game. By default, it is a secure iterator at the cost of performance (create a copy and check when to stop at each iteration).
Be aware that the number of days can be less than maxdays because it will stop when detecting a "stable" game (i.e. when all the cells have the same value).
Arguments
game::Game: the game to iterate overmaxdays::Integer: the maximum number of days to iterate over. Set tonothingto never stop, unless the game is stable andstop_checkis notnothing.
Keywords (optional)
stop_check::Union{Integer, Nothing}: the number of days to wait before checking if the game is stable. If the game is stable, the iterator will stop. Set tonothingto never check.copydays: Iffalse, the iterator will return the same matrix at each iteration, modifying it inplace. DO NOT change it tofalseif you don't know exactly what you are doing.
Example
julia> game = newgame((4, 4), (2, 2), neigh_disk, Int, rng=1);
julia> for day in days(game, 3)
println(day)
end
[1 1 2 2; 1 1 2 2; 3 3 4 4; 3 3 4 4]
[1 2 2 2; 1 1 2 2; 3 3 4 4; 3 3 4 4]
[1 1 2 2; 1 2 4 4; 1 2 3 4; 3 4 4 4]GridSim.endless_days — Functionendless_days(game::Game)Alias for days(game, stop_check=nothing, copydays=false), that is an iterator that will never stop iterating over the game days.
Accessors
You can access some properties of the game, for both game and iterator objects.
GridSim.firstday — Functionfirstday(grid_size::Tuple{Int,Int}, territory_size::Tuple{Int,Int}, fill::Vector)
firstday(grid_size::Tuple{Int,Int}, territory_size::Tuple{Int,Int}, fill::Type)
firstday(game::Game)Return the first day matrix of the game, based on the grid size, the territory size and a vector of values to fill the territories.
The fill argument can also be a type value but only few ones are supported :
<:Real: Fill the territories with the values1, 2, 3, ...of the correct type.RGB: Fill the territories with distinguishable colors.
Example
julia> firstday((4, 4), (2, 2), Int)
4×4 Matrix{Int64}:
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
julia> firstday((4, 4), (2, 2), Int8) # to save memory
4×4 Matrix{Int8}:
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
julia> firstday((4, 4), (2, 2), ["hello", "world"])
ERROR: ArgumentError: The length of the fill vector must be greater than the number of territories.
Number of territories : 4
julia> firstday((4, 4), (2, 2), ["hello", "world", "foo", "bar"])
4×4 Matrix{String}:
"hello" "hello" "world" "world"
"hello" "hello" "world" "world"
"foo" "foo" "bar" "bar"
"foo" "foo" "bar" "bar"GridSim.rules — Functionrules(game::Game)
rules(iter::DaysIterator)Return the GameRules object of the game or the iterator.
GridSim.seedof — Functionseedof(game::Game)
seedof(iter::DaysIterator)Return the seed of the game or the iterator. If the game or the iterator was created with a random number generator (and not a seed), nothing will be returned.
GridSim.game_rng — Functiongame_rng(game::Game)
game_rng(iter::DaysIterator)Return the random number generator of the game or the iterator.
GridSim.gridsize — Functiongridsize(game::Game)
gridsize(iter::DaysIterator)Return the grid size of the game or the iterator as a tuple.
GridSim.grid_indexes — Functiongrid_indexes(game::Game)
grid_indexes(iter::DaysIterator)Return the grid_indexes of the game or the iterator.
Visualization
Here is some utilities to modify the esthetic of the game grids.
GridSim.enlarge — Functionenlarge(M::AbstractMatrix)Enlarge a matrix by a factor λ. Each element of the matrix is repeated λ times in each direction. If M is a n×m matrix, the result will be a nλ×mλ matrix.
Example
julia> M = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> enlarge(M, 2)
4×4 Matrix{Int64}:
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4GridSim.enlarge! — Functionenlarge!(M::AbstractMatrix, container::AbstractMatrix, λ::Int)Inplace version of enlarge. The result is stored in container. The container must be initialized with the correct size (nλ×mλ).
Stats utilities
GridSim.count_values — FunctionGridSim.count_values(array::AbstractArray{T}) -> Dict{T, Int}Return a dictionary with the number of occurences of each value in the array. Elements of the array must be hashable.
Example
julia> GridSim.count_values([1, 2, 3, 2])
Dict{Int64, Int64} with 3 entries:
2 => 2
3 => 1
1 => 1GridSim.most_common — FunctionGridSim.most_common(array::AbstractArray{T}) -> TReturn the most frequent value in the array. If there are multiple values with the maximum number of occurences, the first one is returned.
Example
julia> GridSim.most_common([1, 2, 3, 2])
2
julia> GridSim.most_common([1, 2, 3, 2, 1])
1GridSim.most_commons — FunctionGridSim.most_commons(array::AbstractArray) -> VectorReturn the most frequent value in the array. Faster than the same function from the StatsBase package.
Example
julia> GridSim.most_commons([1, 2, 3, 2, 1])
2-element Vector{Int64}:
2
1