zizroc/villager

Add support for resources

Closed this issue · 0 comments

We'd like to support the notion of resources to villager. Right now, resource information is kept in the VillageState object but will need to be pulled out. See this issue to see how the resources will be integrated.

resource class

A new class should be created to represent each type of resource. The resource class can be thought of as a template for all resources. At a minimum, the resource object should have a name (fish, poultry, etc) and the amount that's currently present. The class should also be an R6 class so that we can modify its state.

When the resource class is finished, new resource objects should be created as

fish <- resource$new(name='fish', quantity=10)
maize <- resource$new(name='maize', quantity=0)

resource_manager class

The resources should be accessed through a new class, called resource_manger. The village class should have an instance of this object, and should also expose it to user defined models (see how winik_manager is used in the propagate function).

This class should have at least two methods: add(resource) and 'get(string resource_name)`.

fish <- resource$new(name='fish', quantity=10)
maize <- resource$new(name='maize', quantity=0)
resource_store <- resource_manager$new()
resource_store$add(fish)
resource_store$add(maize)
maize <- resource_store$get("maize")

Saving & Loading

Eventually we'll want to be able to save the resources and re-load them. This will give similar functionality with the winik manager which will be able to save and load winiks. Like loading winiks, this will allow us to load

The database table describing the resources will look something like the following
resource-table

The resource_manager should have a function, load(), for loading a csv of resources, creating a new resource object for each one, and then adding each new resource object to the manager.

modifying resources in custom models

Users should be able to add and modify resources in their custom models. I added a unit test below (untested so there may be syntax errors) to show what it would look like on the user's end to modify the resource.

test_that("resources can be modified in a model", {
  # Create a model that adds 1 unit of poultry every day, starting with 0
  resource_model <- function(currentState, previousState, modelData, population_manager) {

   # Set the initial conditions at year==1
   if (currentState$year ==1) {
        poultry<- resource$new(name='poultry', quantity=0)
        self$resource_manager$add(poultry)
    }
   else {
         polutry_stock <- resource_manager$get('poultry')
         poultry_stock$quantity <- poultry_stock$quantity + 1
   }
  }

  # Create a default village
  new_state <- VillageState$new()
  plains_village  <- BaseVillage$new(initialState=new_state, models=resource_model)
  # Run for 5 days
  days_to_run <- 5
  new_siumulator <- Simulation$new(length = days_to_run, villages = list(plains_village))
  new_siumulator$run_model()
  testthat::expect_equal(new_siumulator$villages[[1]]$resource_manager$get('poultry'), 5)
})

Unit tests

Two new files, test-winik.R and test-winik_manager.R should be made in the unit test directory. The test_winik tests should test that the constructor works as expected. The test-winik_manager tests should test that

  1. The constructor works
  2. The add method works as expected
  3. The get method works as expected
  4. Modifying a resource's quantity persists

An integrated test should be added (will most likely look like the test I pasted above) to test that

  1. Users can add any number of resources at year==1
  2. Users can modify the quantity of said resources and the quantity persists over time steps