uci.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. use std::collections::BTreeMap;
  2. use engine::{Command, SearchInfo};
  3. use board::Board;
  4. pub fn parse_command(command: &str) -> Result<Command, String> {
  5. let parts = command.split_whitespace().collect::<Vec<&str>>();
  6. if parts.len() > 0 {
  7. let command = parts[0];
  8. let args: Vec<&str> = parts.into_iter().skip(1).collect();
  9. match command {
  10. "uci" => Ok(Command::Uci),
  11. "isready" => Ok(Command::IsReady),
  12. "ucinewgame" => Ok(Command::NewGame),
  13. "setoption" => parse_setoption(&args),
  14. "position" => parse_position(&args),
  15. "go" => parse_go(&args),
  16. "stop" => Ok(Command::Stop),
  17. "quit" | "exit" => Ok(Command::Quit),
  18. /*"isready" => cmd_isready(cmd, r, s),
  19. "position" => cmd_position(cmd, r, s),
  20. "print" => cmd_print(cmd, r, s),
  21. "go" => cmd_go(cmd, r, s),
  22. "stop" => cmd_stop(cmd, r, s),
  23. "ucinewgame" => cmd_newgame(cmd, r, s),
  24. //"setoption" => cmd_setoption(cmd, r, s),
  25. "quit" | "exit" => cmd_quit(cmd, r, s),*/
  26. "" => Ok(Command::Ping),
  27. _cmd => { Err("unknown command".to_owned()) }
  28. }
  29. }
  30. else {
  31. Err("no command".to_owned())
  32. }
  33. }
  34. fn parse_position(args: &Vec<&str>) -> Result<Command, String> {
  35. //let position = args[0];
  36. //args.drain(0..1);
  37. let mut arg_iter = args.iter();
  38. let &position = arg_iter.next().ok_or("no position type argument")?;
  39. let mut board = Board::default();
  40. if position == "startpos" {
  41. }
  42. else if position == "fen" {
  43. let fen_parts: Vec<&str> = arg_iter.by_ref().take(6).map(|p| *p).collect::<Vec<&str>>();
  44. if fen_parts.len() != 6 {
  45. return Err("invalid fen arguments".to_owned());
  46. }
  47. board = Board::from_fen(fen_parts.as_slice()).ok_or("invalid fen")?;
  48. }
  49. else {
  50. return Err("invalid position type".to_owned());
  51. }
  52. let pmov = arg_iter.next();
  53. let moves =
  54. if let Some(&moves) = pmov {
  55. if moves != "moves" {
  56. return Err("expected nothing or 'moves'".to_owned());
  57. }
  58. arg_iter.map(|m| String::from(*m)).collect::<Vec<String>>()
  59. }
  60. else {
  61. Vec::new()
  62. };
  63. Ok(Command::Position{ pos: board, moves })
  64. }
  65. pub fn parse_go(args: &Vec<&str>) -> Result<Command, String> {
  66. let mut options: BTreeMap<String, String> = BTreeMap::new();
  67. let mut opt_name: Option<&str> = None;
  68. let mut si = SearchInfo::new();
  69. for &arg in args {
  70. if let Some(on) = opt_name {
  71. options.insert(on.to_owned(), arg.to_owned());
  72. opt_name = None;
  73. }
  74. else if arg == "infinite" {
  75. si.infinite = true;
  76. }
  77. else if arg == "perft" {
  78. si.perft = true;
  79. }
  80. else {
  81. opt_name = Some(arg);
  82. }
  83. }
  84. si.movetime = options.get("movetime").map(|x| x.parse::<_>().unwrap_or(0));
  85. si.depth = options.get("depth").map(|x| x.parse::<_>().unwrap_or(0));
  86. si.wtime = options.get("wtime").map(|x| x.parse::<_>().unwrap_or(0));
  87. si.btime = options.get("btime").map(|x| x.parse::<_>().unwrap_or(0));
  88. si.winc = options.get("winc").map(|x| x.parse::<_>().unwrap_or(0));
  89. si.binc = options.get("binc").map(|x| x.parse::<_>().unwrap_or(0));
  90. si.movestogo = options.get("movestogo").map(|x| x.parse::<_>().unwrap_or(0));
  91. Ok(Command::Go(si))
  92. }
  93. pub fn parse_setoption(args: &Vec<&str>) -> Result<Command, String> {
  94. enum State {
  95. None,
  96. Name,
  97. Value
  98. }
  99. let mut state = State::None;
  100. let mut name: String = String::new();
  101. let mut value: String = String::new();
  102. let extend_string = |s: &mut String, ex: &str| {
  103. if !s.is_empty() {
  104. s.push_str(" ");
  105. }
  106. s.push_str(ex);
  107. };
  108. for arg in args {
  109. match *arg {
  110. "name" => {
  111. state = State::Name;
  112. },
  113. "value" => {
  114. state = State::Value;
  115. },
  116. any => {
  117. match state {
  118. State::Name => extend_string(&mut name, any),
  119. State::Value => extend_string(&mut value, any),
  120. State::None => return Err("invalid option".to_owned())
  121. }
  122. }
  123. }
  124. }
  125. Ok(Command::SetOption { name: name, val: value })
  126. }