Advertisement
Guest User

Untitled

a guest
Aug 22nd, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 6.45 KB | None | 0 0
  1. use crate::ToggleMap2D::ToggleMap2D;
  2. use std::collections::btree_map::Entry;
  3. use std::collections::BTreeMap;
  4. use screeps::StructureType;
  5. use screeps::objects::Room;
  6. use screeps::RoomPosition;
  7. use screeps::find;
  8. use screeps::ReturnCode;
  9. use screeps::objects::HasPosition;
  10. use log::*;
  11.  
  12. use crate::map::Map;
  13. use crate::MovementCostMap::*;
  14.  
  15. const TILE_NEW: u8 = 0;
  16. const TILE_OPEN: u8 = 1;
  17. const TILE_CLOSED: u8 = 2;
  18. const ROW_LENGTH: u8 = 50;
  19.  
  20. struct MapList<K, V> {
  21.     inner: BTreeMap<K, Vec<V>>
  22. }
  23.  
  24. impl <K, V> MapList<K, V>
  25.     where K:
  26.         std::cmp::Ord + Copy
  27. {
  28.     pub fn new() -> Self {
  29.         MapList {
  30.             inner: BTreeMap::new()
  31.         }
  32.     }
  33.    
  34.     pub fn insert(&mut self, key: K, value: V) {
  35.         self.inner.entry(key).or_insert(Vec::new()).push(value);
  36.     }
  37.    
  38.     pub fn pop_front(&mut self) -> V {
  39.         let key = self.get_low_key();
  40.         if let Entry::Occupied(mut entry) = self.inner.entry(key) {
  41.             let list = entry.get_mut();
  42.             let value = list.remove(0);
  43.             if list.is_empty() {
  44.                 entry.remove_entry();
  45.             }
  46.            
  47.             return value;
  48.         }
  49.        
  50.         panic!("This should never happen.");
  51.     }
  52.    
  53.     pub fn is_empty(&self) -> bool {
  54.         self.inner.is_empty()
  55.     }
  56.    
  57.     fn get_low_key(&self) -> K {
  58.         let min = self.inner.iter().next();
  59.         let (k, _) = min.unwrap();
  60.         *k
  61.     }
  62. }
  63.  
  64. pub struct RoomPlanner {
  65.     room: Room,
  66.     map: Map,
  67.     movement_cost: MovementCostMap,
  68.     open_list: MapList<u32, RoomPosition>,
  69.     tiles: ToggleMap2D
  70. }
  71.  
  72. impl RoomPlanner {
  73.     pub fn new(room: Room) -> Self {
  74.         let mut map = Map::new();
  75.         map.index(room.clone());
  76.         let start_pos = RoomPlanner::select_start_pos(&room);
  77.        
  78.         let mut result = RoomPlanner {
  79.             room: room.clone(),
  80.             movement_cost: MovementCostMap::new(&room, &map, start_pos),
  81.             map: map,
  82.             open_list: MapList::new(),
  83.             tiles: ToggleMap2D::new(2500, 2, 50)
  84.         };
  85.         result.open_list.insert(0, start_pos);
  86.         result.tiles.set(start_pos.x() as usize, start_pos.y() as usize, TILE_OPEN);
  87.         result
  88.     }
  89.  
  90.     pub fn place_site(&mut self, structure_type: StructureType, template: &[&[char]]) {
  91.         let mut found = false;
  92.  
  93.         while !found && !self.open_list.is_empty() {
  94.             let value = self.open_list.pop_front();
  95.             self.set_closed(value);
  96.             self.add_adjacent_tiles(value);
  97.             found = self.can_build(value, template);
  98.  
  99.             if found {
  100.                 self.build(value, structure_type, template);
  101.             }
  102.         }
  103.     }
  104.  
  105.     fn select_start_pos(room: &Room) -> RoomPosition {
  106.         let spawn = &room.find(find::MY_SPAWNS)[0];
  107.         spawn.pos()
  108.     }
  109.  
  110.     fn add_adjacent_tiles(&mut self, pos: RoomPosition) {
  111.         let start_x: i32 = (pos.x() as i32 - 1).max(0);
  112.         let start_y: i32 = (pos.y() as i32 - 1).max(0);
  113.  
  114.         for y in start_y..pos.y() as i32 + 2 {
  115.             for x in start_x..pos.x() as i32 + 2 {
  116.                 if y >= ROW_LENGTH as i32 || x >= ROW_LENGTH as i32 { continue; }
  117.                 if x == pos.x() as i32 && y == pos.y() as i32 { continue; }
  118.  
  119.                 let p = self.room.get_position_at(x as u32, y as u32).unwrap();
  120.                 let weight = self.movement_cost.get_weight(p.clone()) as u32;
  121.  
  122.                 if self.get_tile_state(p) == TILE_NEW {
  123.                     self.set_open(p);
  124.                     self.open_list.insert(weight, p);
  125.                 }
  126.             }
  127.         }
  128.     }
  129.  
  130.     fn set_open(&mut self, pos: RoomPosition) {
  131.         self.tiles.set(pos.x() as usize, pos.y() as usize, TILE_OPEN);
  132.     }
  133.  
  134.     fn set_closed(&mut self, pos: RoomPosition) {
  135.         self.tiles.set(pos.x() as usize, pos.y() as usize, TILE_CLOSED);
  136.     }
  137.  
  138.     fn get_tile_state(&self, pos: RoomPosition) -> u8 {
  139.         self.tiles.get(pos.x() as usize, pos.y() as usize)
  140.     }
  141.  
  142.     fn can_build(&self, pos: RoomPosition, template: &[&[char]]) -> bool {
  143.         for r in 0..template.len() {
  144.             for c in 0..template[r].len() {
  145.                 let x = pos.x() as usize + c;
  146.                 let y = pos.y() as usize + r;
  147.                 let mask = template[r][c];
  148.  
  149.                 match mask {
  150.                     'Y' => continue,
  151.                     'R' => if !self.map.is_buildable(x,  y) { return false },
  152.                     _ => if !self.map.is_buildable(x, y) || self.map.is_road(x, y) { return false; }
  153.                 }
  154.             }
  155.         }
  156.  
  157.         true
  158.     }
  159.  
  160.  
  161.     fn build(&self, pos: RoomPosition, _structure_type: StructureType, template: &[&[char]]) {
  162.         for r in 0..template.len() {
  163.             for c in 0..template[r].len() {
  164.                 let x = pos.x() as usize + c;
  165.                 let y = pos.y() as usize + r;
  166.                 let mask = template[r][c];
  167.  
  168.                 if mask == 'Y' || mask == 'N' || mask == 'R' { continue; }
  169.                 let struc_type = RoomPlanner::mask_to_structure_type(mask);
  170.                 let pos = self.room.get_position_at(x as u32, y as u32).unwrap();
  171.                 let result;
  172.                 match struc_type {
  173.                     Some(t) => result = self.room.create_construction_site(&pos, t),
  174.                     None => { return; }
  175.                 }
  176.                
  177.                 match result {
  178.                     ReturnCode::Ok => info!("Successfully created site at ({}, {})", x, y),
  179.                     _ => info!("Error creating site at ({}, {}): {}", x, y, result as i16)
  180.                 }
  181.             }
  182.         }
  183.     }
  184.  
  185.     fn mask_to_structure_type(mask: char) -> Option<StructureType> {
  186.         match mask {
  187.             'E' => return Some(StructureType::Extension),
  188.             'T' => return Some(StructureType::Tower),
  189.             'C' => return Some(StructureType::Container),
  190.             'X' => return Some(StructureType::Extractor),
  191.             'L' => return Some(StructureType::Lab),
  192.             'I' => return Some(StructureType::Link),
  193.             'U' => return Some(StructureType::Nuker),
  194.             'O' => return Some(StructureType::Observer),
  195.             'P' => return Some(StructureType::PowerSpawn),
  196.             'A' => return Some(StructureType::Rampart),
  197.             'R' => return Some(StructureType::Road),
  198.             'S' => return Some(StructureType::Spawn),
  199.             _ => return None
  200.         }
  201.     }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement