extern State *update_free( State * const state , const double time ) { Entity * const player_entity = & state->player.entity; const TileType non_walkable = TILE_WALL; TileType dst_tile = update_entity( player_entity, & state->map, non_walkable, time ); const int current = tile_at( & state->map, player_entity->position ); if (current == TILE_TRAP) { die(state); } else if (current == TILE_TRADER) { change_state(state, STATE_TRADE); } else if (current == TILE_BOSS) { change_state(state, STATE_BOSS); } if (player_entity->position.x == state->map.width - 1) { state->current_level_no += 1; clean_map_data( & state-> map ); change_level( & state->map, state->current_level_no ); reset_entities( state ); player_entity->position.x = 0; player_entity->destination = player_entity->previous_position = player_entity->position; } for (int i = 0; i < state->enemies_count; i++) { Enemy *enemy = state->enemies + i; update_enemy( enemy, & state->map, time ); if ( POINT_EQ( state->player.entity.position , enemy->entity.position ) ) { die(state); } Boulder * b = boulder_at( state, enemy->entity.destination ); if ( b != NULL ) { cancel_move( & enemy->entity ); swap_enemy_direction( enemy ); } } for (int i = 0; i < state->boulders_count; i++) { Boulder *boulder = state->boulders + i; update_entity( & boulder->entity, & state->map, 0, time ); } return state; }
void DropletCustomOne::change_state ( State new_state ) { state = new_state; switch ( state ) { case COLLABORATING: set_rgb_led ( 0, 0, 250 ); collab_time = get_32bit_time (); break; case LEAVING: set_rgb_led ( 0, 250, 250 ); move_duration ( (last_move_dir + 3) % 6, WALKAWAY_TIME ); case SAFE: set_rgb_led ( 255, 255, 0 ); break; case START_DELAY: start_delay_time = get_32bit_time (); break; case WAITING: cancel_move (); unique_ids.clear (); set_rgb_led ( 0, 255, 0 ); // Clear out all messages in buffer first. while ( check_for_new_messages() ); heartbeat_time = get_32bit_time (); voting_time = get_32bit_time (); send_heartbeat (); break; case SEARCHING: default: reset_rgb_led (); } }
extern State *process_free( State * const state , const int new_keys , const int old_keys ) { Entity * const player_entity = & state->player.entity; int moved = 0; if ( is_moving( player_entity ) == 0 ) { if (new_keys & KEY_UP) { player_entity->destination.y -= 1; moved = 1; } else if (new_keys & KEY_DOWN) { player_entity->destination.y += 1; moved = 1; } else if (new_keys & KEY_LEFT) { player_entity->destination.x -= 1; moved = 1; } else if (new_keys & KEY_RIGHT) { player_entity->destination.x += 1; moved = 1; } } if ( moved ) { const int destination = tile_at( & state->map , player_entity->destination ); const int current = tile_at( & state->map , player_entity->position ); const int antydest = antydestination_tile(state); if ( ( ! POINT_EQ( player_entity->destination , player_entity->previous_position ) ) && ( destination == TILE_STRING && antydest == TILE_STRING ) ) { cancel_move( player_entity ); } else { if (current == TILE_FLOOR && destination != TILE_STRING) { set_tile( & state->map, TILE_STRING, player_entity->position); } else if ( current == TILE_STRING && destination != TILE_FLOOR) { set_tile( & state->map, TILE_FLOOR, player_entity->position); } } Boulder * b = boulder_at( state, player_entity->destination ); if ( b != NULL ) { int i = player_entity->destination.x - player_entity->position.x; int j = player_entity->destination.y - player_entity->position.y; Point boulder_dest; boulder_dest.x = player_entity->destination.x + i; boulder_dest.y = player_entity->destination.y + j; TileType boulder_dest_tile = tile_at( & state->map, boulder_dest); if ( boulder_dest_tile == TILE_FLOOR ) { b->entity.destination = boulder_dest; } else { cancel_move( player_entity ); } } } return state; }
void DropletCustomFive::DropletMainLoop() { switch(state) { case WANDER: if(!wander_rgb) { set_rgb_led(255,0,255); wander_rgb = true; } if(!is_moving()) { move_steps((rand_byte() % 6) + 1, rand_byte() * 50); } if(!first_set) { uint8_t r, g, b; get_rgb_sensor(&r, &g, &b); if(r > 200) { first_set = true; char msg = 'R'; ir_broadcast(&msg, sizeof(msg)); cancel_move(); cancel_rotate(); guitar_id = 0; row_num = 0; num_in_row = 1; state = CALL; break; } } while(check_for_new_messages()) { char let = global_rx_buffer.buf[0]; uint8_t num; uint16_t idnum; switch(let) { case 'V': float dist, theta, phi; range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); num = global_rx_buffer.buf[1]; if(dist<20 && dist>10) { char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'C'; msg[1] = num; ir_broadcast(&msg[0], sizeof(msg)); } break; case 'S': memcpy(&idnum, &global_rx_buffer.buf[1], 2); if(idnum == get_droplet_id()) { target = global_rx_buffer.sender_ID; slot_num = (uint8_t)global_rx_buffer.buf[3]; guitar_id = (uint8_t)global_rx_buffer.buf[4]; cancel_move(); cancel_rotate(); state = DOCK; break; } break; case 'R': first_set = true; break; case 'D': range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); if(dist<30) { rotate_degrees(static_cast<int16_t>(theta+160)); move_steps(NORTH, 30); } break; default: break; } global_rx_buffer.read=true; } break; case DOCK: if(!dock_rgb) { set_rgb_led(150,150,150); dock_rgb = true; } if(!is_moving()) { float dist, theta, phi; if(!range_and_bearing(target, &dist, &theta, &phi)) { state = WANDER; set_rgb_led(0, 0, 0); move_steps((rand_byte() % 6) + 1, rand_byte()*50); break; } if(!is_rotating() && abs(theta) > 2.5f) { rotate_degrees(static_cast<int16_t>(theta)); } if(!is_rotating() && abs(theta) <= 2.5f) { move_steps(NORTH, static_cast<uint16_t>(dist)); } if(dist <= 20) { if(!clock_wise) // rotate around target counter clockwise { rotate_degrees(static_cast<int16_t>(theta-90)); move_steps(NORTH, 2); char msg = 'D'; ir_broadcast(&msg, 1); if(theta>85) { switch(slot_num) { case 0: if(phi < -75 && phi > -180) { cancel_move(); cancel_rotate(); rotate_degrees(static_cast<int16_t>(-180)); clock_wise = true; break; } if(phi<-59 && phi>-61) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 1: if(phi < -75 && phi > -180) { cancel_move(); cancel_rotate(); rotate_degrees(static_cast<int16_t>(-180)); clock_wise = true; break; } if(phi>-1 && phi<1) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 2: if(phi>59 && phi<61) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 3: if(phi<121 && phi>119) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 4: if((phi>179 && phi<181)||(phi>-181 && phi<-179)) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 5: if(phi>-121 && phi<-119) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; default: break; } } } else // rotate around target clockwise { rotate_degrees(static_cast<int16_t>(theta+90)); move_steps(NORTH, 2); char msg = 'D'; ir_broadcast(&msg, 1); if(theta<-85) { switch(slot_num) { case 0: if(phi < -30 && phi > -75) { cancel_move(); cancel_rotate(); rotate_degrees(static_cast<int16_t>(180)); clock_wise = false; break; } if(phi<121 && phi>119) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 1: if(phi < -50 && phi > -75) { cancel_move(); cancel_rotate(); rotate_degrees(static_cast<int16_t>(180)); clock_wise = false; break; } if((phi>177 && phi<181)||(phi<-177 && phi>-181)) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 2: if(phi>-121 && phi<-119) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 3: if(phi>-31 && phi<-29) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 4: if(phi>-1 && phi<1) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 5: if(phi>59 && phi<61) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; default: break; } } } } } if(check_for_new_messages()) { char let = (char)global_rx_buffer.buf[0]; uint8_t num = (uint8_t)global_rx_buffer.buf[1]; switch(let) { case 'A': if(num == guitar_id) { wander_rgb = false; state = WANDER; } case 'F': if(num == guitar_id) { wander_rgb = false; state = WANDER; } break; case 'T': float dist, theta, phi; range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); if(dist<5) { move_steps(SOUTH, 5); if(clock_wise) { cancel_move(); cancel_rotate(); clock_wise = false; rotate_degrees(static_cast<int16_t>(theta+165)); move_steps(NORTH, 20); break; } else { cancel_move(); cancel_rotate(); clock_wise = true; rotate_degrees(static_cast<int16_t>(theta+165)); move_steps(NORTH, 20); break; } } break; default: break; } global_rx_buffer.read = true; } break; case ALIGN: if(!align_rgb) { set_rgb_led(255,0,0); align_rgb = true; } float dist, theta, phi; range_and_bearing(target, &dist, &theta, &phi); rotate_degrees(static_cast<int16_t>(theta)); move_steps(NORTH, static_cast<uint16_t>(dist)); if(dist<5) { cancel_move(); rotate_degrees(static_cast<int16_t>(phi)); if(phi < 2 && phi >-2) { char msg[4]; msg[0] = 'F'; memcpy(&msg[1], &target, sizeof(uint16_t)); msg[3] = slot_num; ir_broadcast(&msg[0], sizeof(msg)); state = PRESET; break; } } while(check_for_new_messages()) { char let = (char)global_rx_buffer.buf[0]; uint8_t num = (uint8_t)global_rx_buffer.buf[1]; switch(let) { case 'A': if(num == guitar_id) { wander_rgb = false; state = WANDER; } case 'F': if(num == guitar_id) { wander_rgb = false; state = WANDER; } break; default: break; } global_rx_buffer.read = true; } break; case CALL: if(!call_rgb) { set_rgb_led(0,255,255); call_rgb = true; } if(!first_search) { find_empty_neighbors(guitar_id, row_num, num_in_row); first_search = true; set_timer(10000, 0); } if(check_timer(0)) { for(uint8_t i=0; i<6; i++) { if((neighbors[i]>0) && (neighbors[i]<200)) { /* this message calls needed droplets */ char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'V'; msg[1] = i; ir_broadcast(&msg[0], sizeof(msg)); } } } else { for(uint8_t i=0; i<6; i++) { if((neighbors[i]>0)) { /* timer hasn't gone off, we're list building and calling out all possible neighbors to see which ones are already there */ char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'N'; msg[1] = neighbors[i]; ir_broadcast(&msg[0], sizeof(msg)); } } } while(check_for_new_messages()) { char let = global_rx_buffer.buf[0]; uint8_t num; uint16_t send_id; switch(let) { case 'C': send_id = global_rx_buffer.sender_ID; num = (uint8_t)global_rx_buffer.buf[1]; if((neighbors[num]>0) && (neighbors[num]<200)) { char msg[5]; memset(&msg[0], 0, 3); msg[0] = 'S'; memcpy(&msg[1], &send_id, sizeof(uint16_t)); msg[3] = num; msg[4] = neighbors[num]; ir_broadcast(&msg[0], sizeof(msg)); neighbors[num] = 255; } break; case 'F': memcpy(&send_id, &global_rx_buffer.buf[1], sizeof(uint16_t)); num = (uint8_t)global_rx_buffer.buf[3]; if(send_id == get_droplet_id()) { set_rgb_led(255, 0, 0); call_rgb = false; neighbors[num] = 0; slots_set++; } break; case 'A': num = (uint8_t)global_rx_buffer.buf[1]; for(uint8_t i=0; i<6; i++) { if((neighbors[i] > 0) && (neighbors[i] == num)) { neighbors[i] = 0; slots_needed--; break; } } break; default: break; } global_rx_buffer.read = true; } if(slots_set == slots_needed) { char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'L'; msg[1] = (guitar_id + 1); ir_broadcast(&msg[0], sizeof(msg)); is_set_rgb = false; state = SET; break; } /*if((neighbors[1])==0 && (neighbors[2]==0) && (neighbors[3]==0) && (neighbors[4]==0) && (neighbors[5]==0)) { char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'L'; msg[1] = (guitar_id + 1); ir_broadcast(&msg[0], sizeof(msg)); is_set_rgb = false; state = SET; break; }*/ break; case PRESET: if(!preset_rgb) { set_rgb_led(0, 255, 0); preset_rgb = true; } set_rgb_led(0, 255, 0); while(check_for_new_messages()) { char let = (char)global_rx_buffer.buf[0]; uint8_t num = (uint8_t)global_rx_buffer.buf[1]; uint8_t num2; switch(let) { case 'S': num2 = (uint8_t)global_rx_buffer.buf[4]; if(num2 == guitar_id) { set_rgb_led(255, 0, 0); char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'A'; msg[1] = guitar_id; ir_broadcast(&msg[0], sizeof(msg)); } break; case 'L': if(num==guitar_id) { row_num = get_row_num(guitar_id); num_in_row = get_num_in_row(guitar_id); call_rgb = false; state = CALL; } break; case 'N': if(num==guitar_id) { set_rgb_led(255, 0, 0); char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'A'; msg[1] = guitar_id; ir_broadcast(&msg[0], sizeof(msg)); } break; case 'D': float dist, theta, phi; range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); if(dist<5) { char msg = 'T'; ir_broadcast(&msg, 1); } break; default: break; } global_rx_buffer.read = true; } break; case SET: if(!is_set_rgb) { set_rgb_led(0,0,255); is_set_rgb = true; } while(check_for_new_messages()) { char let = (char)global_rx_buffer.buf[0]; uint8_t num = (uint8_t)global_rx_buffer.buf[1]; switch(let) { case 'N': if(num==guitar_id) { set_rgb_led(255, 0 , 0); is_set_rgb = false; char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'A'; msg[1] = guitar_id; ir_broadcast(&msg[0], sizeof(msg)); } break; case 'D': float dist, theta, phi; range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); if(dist<5) { char msg = 'T'; ir_broadcast(&msg, 1); } break; default: break; } global_rx_buffer.read = true; } break; } }