Advertisement
Guest User

Untitled

a guest
Jan 18th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.38 KB | None | 0 0
  1. use std::io::{Read,BufRead,Write,stdin,stdout};
  2.  
  3. #[derive(Debug)]
  4. struct Piece{
  5.     value:i64,
  6.     cumulative_value:i64,
  7.     name:String,
  8. }
  9.  
  10. #[derive(Debug)]
  11. struct Player{
  12.     pieces:Vec<Piece>,
  13.     name:String,
  14.     value:i64,
  15. }
  16.  
  17. fn read_confirm<R:BufRead>(read:&mut R)->bool{
  18.     loop{
  19.         print!("\naccept ? [y/n]:");
  20.         stdout().flush().unwrap();
  21.         match read_line(read).as_str(){
  22.             "y"=>{return true;}
  23.             "n"=>{return false;}
  24.             _=>{}
  25.         }
  26.     }
  27. }
  28.  
  29. fn read_num<R:BufRead>(read:&mut R)->i64{
  30.     loop{
  31.         if let Ok(result)=read_line(read).parse(){
  32.             if result>=0 && result<(1<<62){
  33.                 return result;         
  34.             }
  35.         }
  36.         println!("not a valid number, try again");
  37.     }
  38. }
  39.  
  40. fn read_line<R:BufRead>(read:&mut R)->String{
  41.     let mut string=String::new();
  42.     read.read_line(&mut string).unwrap();
  43.     string.trim().into()
  44. }
  45.  
  46. fn read_player<R:BufRead>(read:&mut R)->Player{
  47.     loop{
  48.         print!("name: ");
  49.         stdout().flush().unwrap();
  50.         let name=read_line(read);
  51.         print!("bonus: ");
  52.         stdout().flush().unwrap();
  53.         let bonus=read_num(read);
  54.         print!("\n### piece list (descending importance) ###\nblank name to end list\n\n");
  55.         let mut pieces=Vec::new();
  56.         let mut total=0;
  57.         loop{
  58.             print!("name: ");
  59.             stdout().flush().unwrap();
  60.             let name=read_line(read);
  61.             if name.is_empty(){
  62.                 break;
  63.             }
  64.             print!("value: ");
  65.             stdout().flush().unwrap();
  66.             let value=read_num(read);
  67.             total+=value;
  68.             pieces.push(Piece{name,value,cumulative_value:total});
  69.         }
  70.         let value=pieces.iter().map(|p|p.value).sum::<i64>()+bonus;
  71.         let player=Player{pieces,name,value};
  72.         player.print();
  73.         if read_confirm(read){
  74.             return player;
  75.         }
  76.     }
  77. }
  78.  
  79. impl Player{
  80.     fn print(&self){
  81.         print!("\n### player data ###\n\n");
  82.         print!("name: {:?}\nvalue:{}\npieces:\n",self.name,self.value);
  83.         print!("\t{:^30}|{:^10}|{:^20}|{:^20}|active\n","name","value","cumulative value","lose after");
  84.         for p in &self.pieces{
  85.             let diff=self.value-p.cumulative_value;
  86.             print!("\t{:30}|{:10}|{:20}|{:20}|{}\n",p.name,p.value,p.cumulative_value,diff,diff>=0);
  87.         }
  88.     }
  89.    
  90.     fn find_end_of_active(&self)->usize{
  91.         self.pieces.iter().position(|p|p.cumulative_value< self.value).unwrap_or(self.pieces.len())
  92.     }
  93.    
  94.     fn remove_value_print(&mut self,v:i64){
  95.         let pre_pos=self.find_end_of_active();
  96.         self.value-=v;
  97.         let post_pos=self.find_end_of_active();
  98.         let removed:Vec<&String>=self.pieces[post_pos..pre_pos].iter().map(|p|&p.name).collect();
  99.         if removed.is_empty(){
  100.             return;
  101.         }
  102.         print!("player {}:\n",self.name);
  103.         for p in &removed{
  104.             print!("\tremove {}\n",p);
  105.         }
  106.     }
  107.    
  108.     fn add_value_print(&mut self,v:i64){
  109.         let pre_pos=self.find_end_of_active();
  110.         self.value+=v;
  111.         let post_pos=self.find_end_of_active();
  112.         let added:Vec<&String>=self.pieces[pre_pos..post_pos].iter().map(|p|&p.name).collect();
  113.         if added.is_empty(){
  114.             return;
  115.         }
  116.         print!("player {}:\n",self.name);
  117.         for p in &added{
  118.             print!("\tadd {}\n",p);
  119.         }
  120.     }
  121. }
  122.  
  123. fn parse_num_word(word:Option<&str>,max:usize)->Option<usize>{
  124.     if let Some(word)=word{
  125.         if let Ok(num)=word.parse::<usize>(){
  126.             if num<max{
  127.                 return Some(num);
  128.             }
  129.         }
  130.     }
  131.     None
  132. }
  133.  
  134. fn read_transacion<R:BufRead>(players:&mut [Player],read:&mut R){
  135.     print!("transfer to: ");
  136.     let to=read_player_id(players,read);
  137.     let mut total=0;
  138.     let mut transactions=Vec::new();
  139.     loop{
  140.         print!("transfer from player (blank to end):");
  141.         stdout().flush().unwrap();
  142.         if let Some(id)=read_player_optional(players,read){
  143.             print!("transfer value: ");
  144.             stdout().flush().unwrap();
  145.             let value=read_num(read);
  146.             total+=value;
  147.             transactions.push((id,value));
  148.         }else{
  149.             break;
  150.         }
  151.     }
  152.     print!("confirm transactions");
  153.     for p in &transactions{
  154.         print!("{:30}|{}\n",players[p.0].name,p.1);
  155.     }
  156.     println!("-> {:27}|{}",players[to].name,total);
  157.     if read_confirm(read){
  158.         players[to].add_value_print(total);
  159.         for p in &transactions{
  160.             players[p.0].remove_value_print(p.1);
  161.         }
  162.     }
  163.    
  164. }
  165.  
  166. fn read_player_id<R:BufRead>(players:&[Player],read:&mut R)->usize{
  167.     loop{
  168.         if let Some(p)=read_player_optional(players,read){
  169.             return p;
  170.         }
  171.     }
  172. }
  173.  
  174. fn read_player_optional<R:BufRead>(players:&[Player],read:&mut R)->Option<usize>{
  175.     loop{
  176.         let line=read_line(read);
  177.         if line.is_empty(){
  178.             return None;
  179.         }
  180.         if let Ok(id)=line.parse::<usize>(){
  181.             if id <players.len(){
  182.                 return Some(id);
  183.             }else{
  184.                 println!("invalid player id try again");
  185.                 print_player_list(players);
  186.             }
  187.         }else{
  188.             println!("not a number, try again");
  189.         }
  190.     }
  191. }
  192.  
  193. fn print_player_list(players:&[Player]){
  194.     for i in 0..players.len(){
  195.         println!("{:3}|{}",i,players[i].name);
  196.     }
  197. }
  198.  
  199.  
  200. fn main(){
  201.     let stdin=stdin();
  202.     let mut stdin=stdin.lock();
  203.     print!("number of players: ");
  204.     stdout().flush().unwrap();
  205.     let player_count=read_num(&mut stdin);
  206.     assert!(player_count>=2);
  207.     let mut players=Vec::new();
  208.     for _ in 0..player_count{
  209.         players.push(read_player(&mut stdin));
  210.     }
  211.     loop{
  212.         let line=read_line(&mut stdin);
  213.         let mut words=line.split_whitespace();
  214.         match words.next(){
  215.             Some("p")|Some("print")=>{
  216.                 if let Some(id)=parse_num_word(words.next(),players.len()){
  217.                     players[id].print();               
  218.                 }else{
  219.                     println!("invalid player id");
  220.                 }
  221.             },
  222.             Some("l")|Some("list")=>{
  223.                 print_player_list(&players);
  224.             },
  225.             Some("t")|Some("transfer")=>{
  226.                 read_transacion(&mut players,&mut stdin)
  227.             },
  228.             None|Some("")=>{},
  229.             Some(_)=>println!("invalid command"),
  230.         }
  231.     }
  232. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement