/* * * EDGECITY v1.5 -- The Observer's file * * 'Evolution of Central Places' a model by Paul Krugman * * This simulation is based on the demo model published by P. Krugman, which was * reformulated as an agent-based model by László Gulyás. * It was implemented in MAML v0.03 as an example application. * * (c) 1998, CEU Systems Laboratory * */ // MAML Code for the model to be observed $import "edge.maml"; @observe EdgeCity { @uses ; // We need some mathematical routines // (namely sin and cos) to draw the // circular representation. // MAML code for the Barchart showing the actual // market shares in percentages. $import "ezpercentages.maml.stub"; // Extension of the Firm Agent to be able to // report the actual location (used in connection with // the barchart to visualize market shares). @extendAgent Firm { @sub: (int) getLocation { return loc; } } $define DEGTORAD : "0.017453292"; // Constant for conversion from // degree to radian (used drawing // the circular visualization of // the 'world'). // Observer subroutine to draw the circular representation of the world @sub: (void) updateCircleWorld { int i, d, x, y, r, cx, cy; // Local variables: // i -- loop variable // d -- step in degrees to place // locations around the circle // x,y -- actual position of the dot // cx, // cy -- center of the circle // r -- radius cx = cy = NumOfPlaces / 2 + 1; // Set the parameters r = NumOfPlaces / 2; d = 360 / NumOfPlaces; // Determine step for (i=0; iinfoBank getPercentage: NumOfPlaces-i-1]) ]; } } // Observer subroutine to dynamically update the titles of the // displaying windows @sub: (void) updateTitles { // Constructs the current title in 'titleString', getting // the actual value of TIME by 'getCurrentTime()' sprintf(TitleString, "Market Shares At Step#%ld", getCurrentTime()); // Changes the titles of the displays [sharesBin setTitle: TitleString]; [worldRaster setWindowTitle: TitleString]; } // Definition of what variables to probe (these become editable // at the beginning) @probe: // Model probes var "NumOfPlaces", var "NumOfFirms", var "A", var "B", var "r1", var "r2", var "randomMoveFactor", var "mobility", var "initialFlatness"; // Observer variables connected to the displays @var: EZPercentages sharesBin; // The barchart showing the shares @var: XColormap colormap; // Colorscale used in the circular world @var: ZoomRaster worldRaster; // Display for the circular world @var: string TitleString; // Place to store the window titles // Observation schedule @schedule cyclic (1) { // This is also a cyclic schedule with // cycle length of 1. This means that // the display will be updated in every' // (model) timestep. 0: @planDef seq { // These activities will be performed // exactly in this order @to self updateTitles; // Updates the windows' titles @to sharesBin reset; // These three calls update the @to sharesBin update; // barchart @to sharesBin output; @to self updateCircleWorld; // Redraws the circular representation @to worldRaster drawSelf; // And updates it on the screen } } // Initialization of the observer @init: // Default values for model parameters (which will be shown in the // input fields when the simulation starts). NumOfPlaces = 36; NumOfFirms = 300; A = 1; B = 1; r1 = 0.1; r2 = 0.05; randomMoveFactor = 0; mobility = 0.5; initialFlatness = 5; // Creates the input fields for the parameters... @buildProbes; [model probe]; // ... and stops the simulation to give time to the user to alter them [controlPanel setStateStopped]; // Initializes the model (with the possibly altered parameters) @initModel; // Initialize the observers variables { // This is the beginning of a // {}-block which allows for // safely local variables // (Sorry, it is a technical trick.) int i; // Loop variable (local in this block) // The creation of the colorscale @create XColormap colormap; [colormap setColor: 0 ToName: "blue"]; for (i=1; i<11; i++) [colormap setColor: i ToRed: 0.4+ (double)i*0.06 Green: 0 Blue: 1.0]; for (i=11; i<31; i++) [colormap setColor: i ToRed: 0.4 + (double) (i-11)*0.03 Green: 0 Blue: 0]; for (i=31; i<=100; i++) [colormap setColor: i ToRed: (double) 1.0 Green: 0 Blue: 0]; } // Creation and initialization of the circular world's display @create ZoomRaster worldRaster; [worldRaster setColormap: colormap]; [worldRaster setZoomFactor: 8]; [worldRaster setWidth: NumOfPlaces+2 Height: NumOfPlaces+2]; [worldRaster setWindowTitle: "Market Shares"]; [worldRaster pack]; // Creation and initialization of the barchart @create EZPercentages sharesBin { [sharesBin setTitle: "Market Shares"]; [sharesBin setAxisLabelsX: "Location" Y: "Percentages"]; [sharesBin setBinNum: NumOfPlaces]; [sharesBin setLowerBound: 0]; [sharesBin setUpperBound: NumOfPlaces-1]; [sharesBin setCollection: groupOfFirm]; [sharesBin setProbedSelector: M(getLocation)]; } // These calls display the original distribution of the agents [sharesBin reset]; [sharesBin update]; [sharesBin output]; [self updateCircleWorld]; [worldRaster drawSelf]; }