Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
sim.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  sim.c
4 
5  =============================================================
6 
7  Copyright 1996-2014 Tom Barbalet. All rights reserved.
8 
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation
11  files (the "Software"), to deal in the Software without
12  restriction, including without limitation the rights to use,
13  copy, modify, merge, publish, distribute, sublicense, and/or
14  sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following
16  conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  OTHER DEALINGS IN THE SOFTWARE.
29 
30  This software and Noble Ape are a continuing work of Tom Barbalet,
31  begun on 13 June 1996. No apes or cats were harmed in the writing
32  of this software.
33 
34  ****************************************************************/
35 
36 #define CONSOLE_REQUIRED
37 #define CONSOLE_ONLY
38 
39 #include <stdio.h>
40 
41 #ifndef _WIN32
42 #include "../entity/entity.h"
43 #else
44 #include "..\entity\entity.h"
45 #endif
46 
47 #include "universe_internal.h"
48 
49 #ifndef _WIN32
50 
51 #include <pthread.h>
52 
53 #endif
54 
55 static variable_string apescript_variable_codes[VARIABLE_MAX]=
56 {
57  /* special "variables" */
58  "function",
59  "run",
60 
61  "while",
62  "if",
63 
64  /* output only */
65  "vector_x",
66  "vector_y",
67 
68  "random",
69  "water_level",
70 
71  "biology_area",
72  "biology_height",
73 
74  "biology_water",
75  "biology_moving_sun",
76 
77  "biology_total_sun",
78  "biology_salt",
79  "biology_bush",
80 
81  "biology_grass",
82  "biology_tree",
83 
84  "biology_seaweed",
85  "biology_rockpool",
86  "biology_beach",
87 
88  "biology_insect",
89  "biology_mouse",
90 
91  "biology_parrot",
92  "biology_lizard",
93 
94  "biology_eagle",
95  "biology_output",
96 
97  "hungry",
98  "energy",
99  "location_z",
100 
101  "test_z",
102  "is_visible",
103 
104  "time",
105  "date",
106 
107  "current_being",
108  "number_beings",
109 
110  "location_x",
111  "location_y",
112 
113  "state",
114 
115  "id_number",
116  "date_of_birth",
117 
118  "is_error",
119  "weather",
120 
121  "brain_value", /* special input/output */
122  /* actual variables start here */
123 
124  "vector_angle",
125  "facing",
126 
127  "speed",
128  "energy_delta",
129 
130  "honor",
131  "parasites",
132  "height",
133 
134  "first_name",
135  "family_name_one",
136  "family_name_two",
137 
138  "goal_type",
139  "goal_x",
140  "goal_y",
141 
142  "drive_hunger",
143  "drive_social",
144  "drive_fatigue",
145  "drive_sex",
146 
147  "brain_x",
148  "brain_y",
149 
150  "brain_z",
151  "select_being",
152 
153  "test_x",
154  "test_y",
155 
156  "biology_operator",
157 
158  "posture",
159 
160  "preference_mate_height_male",
161  "preference_mate_height_female",
162  "preference_mate_pigment_male",
163  "preference_mate_pigment_female",
164  "preference_mate_hair_male",
165  "preference_mate_hair_female",
166  "preference_mate_frame_male",
167  "preference_mate_frame_female",
168  "preference_groom_male",
169  "preference_groom_female",
170  "preference_anecdote_event",
171  "preference_anecdote_affect",
172  "preference_chat",
173 
174  "attention_actor_index",
175  "attention_episode_index",
176  "attention_body_index",
177 
178  "shout_content",
179  "shout_heard",
180  "shout_counter",
181  "shout_volume",
182  "shout_family_first",
183  "shout_family_last",
184 
185  "social_graph_location_x",
186  "social_graph_location_y",
187  "social_graph_time",
188  "social_graph_date",
189  "social_graph_attraction",
190  "social_graph_fof",
191  "social_graph_familiarity",
192  "social_graph_first_name",
193  "social_graph_family_first",
194  "social_graph_family_last",
195 
196  "memory_location_x",
197  "memory_location_y",
198  "memory_time",
199  "memory_date",
200  "memory_first_name_zero",
201  "memory_family_first_zero",
202  "memory_family_last_zero",
203  "memory_first_name_one",
204  "memory_family_first_one",
205  "memory_family_last_one",
206  "memory_event",
207  "memory_affect",
208 
209  "being"
210 };
211 
213 
214 /* Twice the minimum number of apes the Simulation will allow to run */
215 #define MIN_BEINGS 4
216 
217 static noble_simulation sim;
218 
219 static n_interpret *interpret = 0L;
220 
221 static n_int sim_new_progress = 0;
222 
224 {
225  return sim_new_progress;
226 }
227 
228 #ifndef _WIN32
229 
230 static n_int sim_quit_value = 0;
231 static pthread_t threads[2] = {0};
232 static n_byte threads_running[2] = {0};
233 
235 {
236  return sim_quit_value;
237 }
238 
239 static void sim_console_clean_up(void)
240 {
241  if ((io_command_line_execution() == 0) || sim_quit_value)
242  {
243  return;
244  }
245 
246  sim_quit_value = 1;
247 
248  console_quit(0L,0L,0L);
249 
250  while (console_executing()) {}
251 }
252 
253 
254 
255 static void *sim_thread_posix(void *threadid)
256 {
257  n_byte *local = (n_byte *)threadid;
258  if (io_console(&sim, (noble_console_command *) control_commands, io_console_entry_clean, io_console_out) != 0)
259  {
260  sim_console_clean_up();
261  }
262  local[0] = 0;
263  pthread_exit(0L);
264 }
265 
267 {
268  if (io_command_line_execution() == 0)
269  {
270  return;
271  }
272 
273  if ((threads_running[0] == 0)||(threads_running[1] == 0))
274  {
275  n_int loop = 0;
276  while (loop < 2)
277  {
278  if (threads_running[loop] == 0)
279  {
280  threads_running[loop] = 1;
281  pthread_create(&threads[loop], 0L, sim_thread_posix, &threads_running[loop]);
282  return;
283  }
284  loop++;
285  }
286  }
287 }
288 
289 #endif
290 
292 {
293  return &sim;
294 }
295 
297 {
298  sim.real_time = time;
299 }
300 
302 {
303  input_file->size = input_file->location;
304  input_file->location = 0;
305 
306  interpret = parse_convert(input_file, VARIABLE_BEING, (variable_string *)apescript_variable_codes);
307 
308  if(interpret == 0L)
309  {
310  return -1;
311  }
312  else
313  {
314  SC_DEBUG_ON(sim.select); /* turn on debugging after script loading */
315  }
316 
317  interpret->sc_input = &sketch_input;
318  interpret->sc_output = &sketch_output;
319 
320  interpret->input_greater = VARIABLE_WEATHER;
321  interpret->special_less = VARIABLE_VECT_X;
322  return 0;
323 }
324 
325 #ifdef BRAIN_ON
326 static void sim_brain_loop(noble_simulation * local_sim, noble_being * local_being, void * data)
327 {
328  n_byte2 local_brain_state[3];
329 
330  if(being_brainstates(local_being, (being_awake(&sim, local_being) == 0), local_brain_state))
331  {
332  n_byte *local_brain = being_brain(local_being);
333  if (local_brain != 0L)
334  {
335  brain_cycle(local_brain, local_brain_state);
336  }
337  }
338 }
339 #endif
340 
341 
342 #ifdef BRAINCODE_ON
343 
344 static void sim_brain_dialogue_loop(noble_simulation * local_sim, noble_being * local_being, void * data)
345 {
346  n_byte awake = 1;
347  n_byte *local_internal = being_braincode_internal(local_being);
348  n_byte *local_external = being_braincode_external(local_being);
349  if(being_awake(&sim, local_being) == 0)
350  {
351  awake=0;
352  }
353  /* This should be independent of the brainstate/cognitive simulation code */
354  brain_dialogue(local_sim, awake, local_being, local_being, local_internal, local_external, being_random(local_being)%SOCIAL_SIZE);
355  brain_dialogue(local_sim, awake, local_being, local_being, local_external, local_internal, being_random(local_being)%SOCIAL_SIZE);
356 }
357 
358 #endif
359 
360 
361 static void sim_being_universal_loop(noble_simulation * local_sim, noble_being * local_being, void * data)
362 {
363  being_cycle_universal(local_sim,local_being, (being_awake(local_sim, local_being) != 0));
364 }
365 
366 static void sim_being_cycle(noble_simulation * local_sim, noble_being * local_being, void * data)
367 {
368  if (being_awake(local_sim, local_being) == 0) return;
369 
370  being_cycle_awake(local_sim, local_being);
371 }
372 
373 static void sim_being_interpret(noble_simulation * local_sim, noble_being * local_being, void * data)
374 {
375  n_individual_interpret individual;
376 
377  interpret_individual(&individual);
378 
379  if (being_awake(local_sim, local_being) == 0) return;
380 
381  if (interpret == 0L) return;
382 
383  if(interpret_cycle(interpret, &individual, -1,
384  local_sim->beings, local_being,
386  {
387  interpret_cleanup(&interpret);
388  }
389 }
390 
391 
392 static void sim_time(noble_simulation * local_sim)
393 {
394  local_sim->count_cycles += local_sim->num;
395 
396  local_sim->count_frames ++;
397 
398  if ((local_sim->real_time - local_sim->last_time) > 60)
399  {
400  local_sim->last_time = local_sim->real_time;
401  local_sim->delta_cycles = local_sim->count_cycles;
402  local_sim->delta_frames = local_sim->count_frames;
403  local_sim->count_cycles = 0;
404  local_sim->count_frames = 0;
405  }
406 }
407 
408 void sim_cycle(void)
409 {
410  n_int max_honor = 0;
411 
412  land_cycle(sim.land);
413 #ifdef WEATHER_ON
414  weather_cycle(sim.land);
415 #endif
416 
417  being_loop(&sim, sim_being_universal_loop, 32);
418 
419  if (interpret)
420  {
421  being_loop(&sim, sim_being_interpret, 16);
422  }
423  else
424  {
426  being_loop(&sim, being_listen, 64);
427 #ifdef EPISODIC_ON
428  being_loop(&sim, episodic_cycle, 64);
429 #endif
430  being_loop(&sim, sim_being_cycle, 8);
431  being_loop(&sim, drives_cycle, 32);
432  }
433 
434  if (sim.land->time & 1)
435  {
436 #ifdef BRAIN_ON
437  being_loop(&sim, sim_brain_loop, 16);
438 #endif
439  }
440 #ifdef BRAINCODE_ON
441  else
442  {
443  being_loop(&sim, sim_brain_dialogue_loop, 8);
444  }
445 #endif
446 
447  being_loop_no_thread(&sim, 0L, being_tidy_loop, &max_honor);
448 
449  being_loop(&sim, social_initial_loop, 32);
450 
451  if (max_honor)
452  {
454  }
455 
457 
458  {
460  if (sim.ext_death != 0L)
461  {
463  }
464  being_loop_no_thread(&sim, 0L, being_remove_loop2, brls);
465  being_remove_final(&sim, &brls);
466  }
467 
468  sim_time(&sim);
469 }
470 
471 #define MINIMAL_ALLOCATION (sizeof(n_land)+(MAP_AREA)+(2*HI_RES_MAP_AREA)+(HI_RES_MAP_AREA/8)+(512*512)+(TERRAIN_WINDOW_AREA)+(sizeof(noble_being) * MIN_BEINGS)+1+(sizeof(noble_simulation)))
472 
473 #define MAXIMUM_ALLOCATION (MINIMAL_ALLOCATION + (sizeof(noble_being) * 200))
474 
475 static void sim_memory_land(noble_simulation * local, n_byte * buffer, n_uint * location)
476 {
477  local->land = (n_land *) & buffer[ *location ];
478  *location += sizeof(n_land);
479 }
480 
481 static void sim_memory_remains(noble_simulation * local, n_byte * buffer, n_uint * location)
482 {
483  local->remains = (noble_remains *) & buffer[ *location ];
484  *location += sizeof(noble_remains);
485 }
486 
487 static n_int sim_memory(n_uint offscreen_size)
488 {
489  n_uint current_location = 0;
490  n_uint memory_allocated = MAXIMUM_ALLOCATION;
491 
492  if (memory_allocated < MINIMAL_ALLOCATION)
493  {
494  return SHOW_ERROR("Not enough memory to run");
495  }
496 
497  offbuffer = io_new_range(offscreen_size + MINIMAL_ALLOCATION, &memory_allocated);
498 
499  current_location = offscreen_size;
500 
501  sim_memory_land(&sim, offbuffer, &current_location);
502 
503  sim_memory_remains(&sim, offbuffer, &current_location);
504 
505  memory_allocated = memory_allocated - offscreen_size - current_location;
506 
507  return being_memory(&sim, offbuffer, &current_location, memory_allocated);
508 }
509 
510 void * sim_init(KIND_OF_USE kind, n_uint randomise, n_uint offscreen_size, n_uint landbuffer_size)
511 {
512  n_byte2 local_random[2];
513 
514  sim_new_progress = 1;
515 
516  if (kind == KIND_NEW_SIMULATION)
517  {
518  if(interpret)
519  {
520  interpret_cleanup(&interpret);
521  interpret = 0L;
522  }
523  }
524  sim.delta_cycles = 0;
525  sim.count_cycles = 0;
526  sim.delta_frames = 0;
527  sim.count_frames = 0;
528  sim.real_time = randomise;
529  sim.last_time = randomise;
530 
531  sim.ext_birth = 0L;
532  sim.ext_death = 0L; /*&console_capture_death; */
533 #ifdef FIXED_RANDOM_SIM
534  randomise = FIXED_RANDOM_SIM;
535 #endif
536  if ((kind == KIND_START_UP) || (kind == KIND_MEMORY_SETUP))
537  {
538  if (sim_memory(offscreen_size) != 0)
539  {
540  return 0L;
541  }
542  execute_init();
543  }
544  if ((kind != KIND_LOAD_FILE) && (kind != KIND_MEMORY_SETUP))
545  {
546  local_random[0] = (n_byte2)(randomise >> 16) & 0xffff;
547  local_random[1] = (n_byte2)(randomise & 0xffff);
548 
549  sim.land->genetics[0] = (n_byte2)(((math_random(local_random) & 255) << 8) | (math_random(local_random) & 255));
550  sim.land->genetics[1] = (n_byte2)(((math_random(local_random) & 255) << 8) | (math_random(local_random) & 255));
551  }
552 
553  being_remains_init(&sim); /* Eventually this should be captured through the file handling and moved into the code below */
554 
555  if (kind != KIND_MEMORY_SETUP)
556  {
557  land_clear(sim.land, kind, AGE_OF_MATURITY);
558 #ifdef LAND_ON
559  land_init(sim.land, &offbuffer[landbuffer_size], 1);
560  land_tide(sim.land);
561 #endif
562  if (kind != KIND_LOAD_FILE)
563  {
564 #if (MAPBITS == 8)
565  n_uint count_to = sim.max >> 2;
566 #else
567  n_uint count_to = sim.max >> 4;
568 #endif
569 #ifdef WEATHER_ON
570  weather_init(sim.land);
571 #endif
572  sim.num = 0;
573  while (sim.num < count_to)
574  {
575  math_random3(local_random);
576  if((sim.num + 1) < sim.max)
577  {
578  if (being_init(sim.land, sim.beings, sim.num, &sim.beings[sim.num], 0L, local_random) != 0)
579  {
580  being_erase(&sim.beings[sim.num]);
581  break;
582  }
583  else
584  {
585  sim.num++;
586  }
587  }
588  }
589  }
590  }
591 
592  sim_set_select(sim.beings);
593 
594  sim_new_progress = 0;
595 
596  return ((void *) offbuffer);
597 }
598 
599 void sim_close(void)
600 {
601  console_quit(0L, 0L, 0L);
602  io_console_quit();
603  execute_close();
604 #ifndef _WIN32
605  sim_console_clean_up();
606 #endif
607  interpret_cleanup(&interpret);
608  io_free((void **) &offbuffer);
609  /*death_record_file_cleanup();*/
610 }
611 
613 {
614  sim.select = select;
616 }
617 
618 static void sim_flood_loop(noble_simulation * sim, noble_being * local, void * data)
619 {
620  n_int local_x = APESPACE_TO_MAPSPACE(being_location_x(local));
621  n_int local_y = APESPACE_TO_MAPSPACE(being_location_y(local));
622  n_int local_z = land_location(sim->land, local_x, local_y);
623 
624  if (local_z < 160)
625  {
626  being_dead(local);
627  }
628 }
629 
630 void sim_flood(void)
631 {
632  being_loop_no_thread(&sim, 0L, sim_flood_loop, 0L);
633 }
634 
636 {
637  n_uint loop = (sim.num >> 2);
638 
639  while (loop < sim.num)
640  {
641  noble_being * local = &sim.beings[loop];
642  being_dead(local);
643  loop++;
644  }
645 }