extern crate rayon;
use rayon::prelude::*;
use rayon::vec::*;
use rayon::vec::IntoIter;
#[derive(Debug)]
enum Message{
Attack{dest_unit_uid:u32, tool_info:String}
}
trait DrawContext{

}
trait Unit:'static + Sync +Send{
// add code here
fn get_uid(&self)->u32;
fn update(&self, user_list:&Vec<Box<Unit>>)->Vec<Message> ;
fn draw(&self, dc:&mut DrawContext);
fn get_location(&self)->(i32, i32);
fn set_location(&mut self,i32, i32);
fn get_hp(&self)->Result<i32,String>{
return Err(String::from(""));
}
fn get_mp(&self)->Result<i32,String>{
return Err(String::from(""));
}
}
#[derive(Debug)]
struct CommonUnit{
uid:u32,
hp:i32,
mp:i32,
pos:(i32,i32)
}
impl CommonUnit{
fn new(uid:u32, hp:i32, mp:i32, x:i32, y:i32)->CommonUnit{
CommonUnit{
uid:uid,
hp:hp,
mp:mp,
pos:(x,y)
}
}
}
impl Unit for CommonUnit {
// add code here
fn get_uid(&self)->u32{
self.uid
}
fn update(&self, user_list:&Vec<Box<Unit>>)->Vec<Message>{
panic!("Common Unit Has Not Update!");
}
fn draw(&self, dc:&mut DrawContext){
}
fn get_location(&self)->(i32, i32){
return self.pos.clone();
}
fn set_location(&mut self, x:i32, y:i32){
self.pos = (x,y);
}
}
#[derive(Debug)]
struct Marine{
unit:CommonUnit
}
impl Marine{
fn new(uid:u32, x:i32, y:i32)->Marine{
Marine{
unit:CommonUnit::new(uid, 40, 0, x, y)
}
}
}
impl Unit for Marine {
// add code here
fn get_uid(&self)->u32{
self.unit.get_uid()
}
fn update(&self, user_list:&Vec<Box<Unit>>)->Vec<Message>{
println!("{:?}",self);
let pos = self.get_location();
let res:Vec<Message> = user_list.iter().filter(|it|{
let (x,y) = it.get_location();
let (x2,y2) = pos.clone();
let (dx, dy) = (x-x2, y - y2);
let distance = dx * dx + dy * dy;
distance <= 10 * 10
}).map(|it|{
Message::Attack{
dest_unit_uid:it.get_uid(), tool_info:String::from("null")
}
}).collect();
return res;
}
fn draw(&self, dc:&mut DrawContext){

}
fn get_location(&self)->(i32, i32){
return self.unit.get_location();
}
fn set_location(&mut self, x:i32, y:i32){
self.unit.set_location(x,y);
}
}
#[derive(Debug)]
struct SiegeTank{
unit:CommonUnit
}
impl SiegeTank{
fn new(uid:u32, x:i32, y:i32)->SiegeTank{
SiegeTank{
unit:CommonUnit::new(uid, 150, 0, x, y)
}
}
}
impl Unit for SiegeTank {
// add code here
fn get_uid(&self)->u32{
self.unit.get_uid()
}
fn update(&self, user_list:&Vec<Box<Unit>>)->Vec<Message>{
println!("{:?}",self);
let pos = self.get_location();
let res:Vec<Message> = user_list.iter().filter(|it|{
let (x,y) = it.get_location();
let (x2,y2) = pos.clone();
let (dx, dy) = (x-x2, y - y2);
let distance = dx * dx + dy * dy;
distance <= 10 * 10
}).map(|it|{
Message::Attack{
dest_unit_uid:it.get_uid(), tool_info:String::from("null")
}
}).collect();
return res;
}
fn draw(&self, dc:&mut DrawContext){

}
fn get_location(&self)->(i32, i32){
return self.unit.get_location();
}
fn set_location(&mut self, x:i32, y:i32){
self.unit.set_location(x,y);
}
}
fn main() {
let mut uid:u32 = 1;
let mut unit_list = Vec::<Box<Unit>>::new();
unit_list.push(Box::new(SiegeTank::new(uid, 560, 250)));
uid += 1;
unit_list.push(Box::new(Marine::new(uid, 50, 50)));
uid += 1;
unit_list.push(Box::new(SiegeTank::new(uid, 500, 250)));
uid += 1;
unit_list.push(Box::new(Marine::new(uid, 50, 45)));
uid += 1;
{
let a = &unit_list;
let mut v = Vec::<Message>::new();
let s:Vec< _ > = unit_list.par_iter().map(move|p| p.update(a)).collect();
for mut it in s {
v.append(&mut it);
}
println!("{:?}",v);
}
}


SiegeTank와 Marine은 CommonUnit이란 구조체를 상속받아서 Unit이란 특성을 구현한 것.