use std::thread;
use std::time::Duration;
use std::sync::mpsc;
use usiagent::selfmatch::*;
use usiagent::shogi::*;
use usiagent::command::*;
use usiagent::event::*;
use usiagent::error::*;
use super::*;
#[test]
fn test_resign_and_quit_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,7),KomaDstToPosition(1,6,false)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Resign)
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,3),KomaDstToPosition(9,4,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Resign(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
None,
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_resign_and_quit_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,7),KomaDstToPosition(1,6,false)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Resign)
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,3),KomaDstToPosition(9,4,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Resign(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
None,
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_invalidmove_and_quit_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,7),KomaDstToPosition(1,6,false)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(8,8),KomaDstToPosition(7,8,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,3),KomaDstToPosition(9,4,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::InvalidMove)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
None,
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_invalidmove_and_quit_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,7),KomaDstToPosition(1,6,false)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(8,8),KomaDstToPosition(7,8,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,3),KomaDstToPosition(9,4,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::InvalidMove)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
None,
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_invalidmove_by_no_responded_oute_and_quit_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(8,8),KomaDstToPosition(3,3,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(6,1),KomaDstToPosition(6,2,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::NotRespondedOute)) => {
if t == Teban::Gote {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("startpos moves 7g7f 3c3d"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_invalidmove_by_no_responded_oute_and_quit_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(8,8),KomaDstToPosition(3,3,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(6,1),KomaDstToPosition(6,2,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::NotRespondedOute)) => {
if t == Teban::Gote {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("startpos moves 7g7f 3c3d"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_invalidmove_by_suicide_and_quit_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(5,8),KomaDstToPosition(5,9,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::Suicide)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("startpos moves 5i5h 3c3d 7g7f 2b7g"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_invalidmove_by_suicide_and_quit_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(5,8),KomaDstToPosition(5,9,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::Suicide)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("startpos moves 5i5h 3c3d 7g7f 2b7g"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_win_move_and_quit_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(5,2),KomaDstToPosition(5,1,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Win(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen lnsgkgsnl/1r2G2b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGK1SNL b - 1"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(1000)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(1000)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_win_move_and_quit_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(5,2),KomaDstToPosition(5,1,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Win(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen lnsgkgsnl/1r2G2b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGK1SNL b - 1"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_win_invalidmove_put_fu_and_mate_and_quit_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::Put(MochigomaKind::Fu,KomaDstPutPosition(5,2)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::PutFuAndMate)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen 3nkn3/3s1s3/9/4L4/9/9/1PPPPPPPP/1B5R1/LNSGK1SNL b Prb2g2sl9p 1"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_win_invalidmove_put_fu_and_mate_and_quit_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::Put(MochigomaKind::Fu,KomaDstPutPosition(5,2)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::PutFuAndMate)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen 3nkn3/3s1s3/9/4L4/9/9/1PPPPPPPP/1B5R1/LNSGK1SNL b Prb2g2sl9p 1"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_win_invalidmove_sennichite_by_oute_once_move_and_quit_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(4,3),KomaDstToPosition(5,3,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::SennichiteOu)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen 4k4/9/5R3/9/9/9/PPPPPPPPP/1B52/LNSGKGSNL b rb2g2s2n2l9p 1 moves 4c5c 5a4a 5c4c 4a5a"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_win_invalidmove_sennichite_by_oute_once_move_and_quit_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(4,3),KomaDstToPosition(5,3,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Foul(t,FoulKind::SennichiteOu)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen 4k4/9/5R3/9/9/9/PPPPPPPPP/1B52/LNSGKGSNL b rb2g2s2n2l9p 1 moves 4c5c 5a4a 5c4c 4a5a"))),
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_nyugyoku_win_win_sente_and_quit_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,4),KomaDstToPosition(1,3,true)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Win)
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,6),KomaDstToPosition(9,7,true)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::NyuGyokuWin(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen ln5n+P/1+R+B1K3+P/+P+P+P+P+P2+P1/ln6P/9/pp5NL/2+p1+p+p+p+p+p/2+b1k3+p/+pN5NL b R2G2S2g2s 1"))),
None,
input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_nyugyoku_win_win_sente_and_quit_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,4),KomaDstToPosition(1,3,true)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Win)
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,6),KomaDstToPosition(9,7,true)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::NyuGyokuWin(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen ln5n+P/1+R+B1K3+P/+P+P+P+P+P2+P1/ln6P/9/pp5NL/2+p1+p+p+p+p+p/2+b1k3+p/+pN5NL b R2G2S2g2s 1"))),
None,
input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_nyugyoku_win_lose_sente_and_winner() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,6),KomaDstToPosition(1,5,false)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Win)
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,6),KomaDstToPosition(9,7,true)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::NyuGyokuLose(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen ln5n+P/1+R+B1K3+P/+P+P+P+P+P2+P1/ln6P/9/pp5NL/2+p1+p+p+p+p+p/2+b1k3+p/+pN5NL b R2G2S2g2s 1"))),
None,
input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_nyugyoku_win_lose_sente_and_loser() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,6),KomaDstToPosition(1,5,false)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Win)
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,6),KomaDstToPosition(9,7,true)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::NyuGyokuLose(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
Some(Box::new(|| String::from("sfen ln5n+P/1+R+B1K3+P/+P+P+P+P+P2+P1/ln6P/9/pp5NL/2+p1+p+p+p+p+p/2+b1k3+p/+pN5NL b R2G2S2g2s 1"))),
None,
input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_quit_thiking() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,7),KomaDstToPosition(1,6,false)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
thread::sleep(Duration::from_millis(350));
Ok(BestMove::Resign)
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,3),KomaDstToPosition(9,4,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Resign(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
None,
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(500)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}
#[test]
fn test_resign_and_quit_after_dummy_command() {
let (pms1,pmr1) = mpsc::channel();
let (pns1,_) = mpsc::channel();
let (ts,tr) = mpsc::channel();
let (pms2,pmr2) = mpsc::channel();
let (pns2,_) = mpsc::channel();
let pmr = [pmr1,pmr2];
let logger = StdErrorLogger::new();
let (input_reader,s) = {
let (s,r) = mpsc::channel();
let input_reader = MockInputReader::new(r);
(input_reader,s)
};
let (output_writer,_) = {
let (s,r) = mpsc::channel();
let output_writer = MockOutputWriter::new(s);
(output_writer,r)
};
let output_writer = Arc::new(Mutex::new(output_writer));
let (es,er) = mpsc::channel();
let _ = thread::spawn(move || {
let player1 = MockPlayer::new(pms1,pns1,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
}),
Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
}),
Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,7),KomaDstToPosition(1,6,false)),None))
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Resign)
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
thread::sleep(Duration::from_millis(350));
Ok(BestMove::Move(Move::To(KomaSrcPosition(1,7),KomaDstToPosition(1,6,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Lose => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let player2 = MockPlayer::new(pms2,pns2,
ConsumedIterator::new(vec![Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
}),
Box::new(|player,_| {
let _ = player.sender.send(Ok(ActionKind::TakeReady));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
}),
Box::new(|player| {
let _ = player.sender.send(Ok(ActionKind::NewGame));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
}),
Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::SetPosition));
Ok(())
})]),
ConsumedIterator::new(vec![Box::new(|player,_,_,_,_,_,_| {
let _ = player.sender.send(Ok(ActionKind::Think));
Ok(BestMove::Move(Move::To(KomaSrcPosition(9,3),KomaDstToPosition(9,4,false)),None))
})]),
ConsumedIterator::new(vec![]),
ConsumedIterator::new(vec![Box::new(|player,s,_| {
match s {
&GameEndState::Win => {
let _ = player.sender.send(Ok(ActionKind::GameOver));
thread::sleep(Duration::from_millis(350));
},
_ => {
let _ = player.sender.send(Err(String::from("gameend state is invalid.")));
}
}
Ok(())
})])
);
let (is,_) = mpsc::channel();
let info_sender = MockInfoSender::new(is);
let mut engine = SelfMatchEngine::new();
let input_read_handler = create_input_read_handler(&engine.system_event_queue);
let _ = engine.start(|self_match_event_dispatcher| {
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameStart, move |_,e| {
match e {
&SelfMatchEvent::GameStart(n,t,_) => {
if t == Teban::Sente && n == 1 {
let _ = hes.send(Ok(EventState::GameStart));
} else {
let _ = hes.send(Err(String::from("GameStart event is invalid.")));
}
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Moved, move |_,e| {
match e {
&SelfMatchEvent::Moved(_,_) => {
let _ = hes.send(Ok(EventState::Moved));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::GameEnd, move |_,e| {
match e {
&SelfMatchEvent::GameEnd(SelfMatchGameEndState::Resign(t)) => {
if t == Teban::Sente {
let _ = hes.send(Ok(EventState::GameEnd));
} else {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
},
_ => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
}
}
Ok(())
});
let hes = es.clone();
self_match_event_dispatcher
.add_handler(SelfMatchEventKind::Abort, move |_,e| {
match e {
&SelfMatchEvent::Abort => {
let _ = hes.send(Err(String::from("GameEnd event is invalid.")));
Ok(())
},
e => Err(EventHandlerError::InvalidState(e.event_kind())),
}
});
},
|| false,
None,
None, input_reader, input_read_handler,
player1,player2,
create_options(), create_options(),
info_sender,
USIPeriodicallyInfo::new(output_writer,false),
UsiGoTimeLimit::None,
None,None,
logger, |h,e| {
if let Some(h) = h {
let _ = h.lock().map(|h| h.call(e));
}
}
);
let _ = ts.send(());
});
startup(&pmr);
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::Moved timed out.");
assert_eq!(res,Ok(EventState::Moved));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let res = er.recv_timeout(Duration::from_millis(60)).expect("attempt to receive EventState::GameEnd timed out.");
assert_eq!(res,Ok(EventState::GameEnd));
let res = pmr[1].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
let _ = s.send(String::from("dummy"));
let res = pmr[0].recv_timeout(Duration::from_millis(600)).expect("attempt to receive ActionKind::GameOver timed out.");
assert_eq!(res,Ok(ActionKind::GameOver));
gamestart_process(&pmr);
let res = er.recv_timeout(Duration::from_millis(300)).expect("attempt to receive EventState::GameStart timed out.");
assert_eq!(res,Ok(EventState::GameStart));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::SetPosition timed out.");
assert_eq!(res,Ok(ActionKind::SetPosition));
let res = pmr[0].recv_timeout(Duration::from_millis(60)).expect("attempt to receive ActionKind::Think timed out.");
assert_eq!(res,Ok(ActionKind::Think));
let _ = s.send(String::from("quit"));
let res = pmr[0].recv_timeout(Duration::from_millis(1000)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let res = pmr[1].recv_timeout(Duration::from_millis(1000)).expect("attempt to receive ActionKind::Quit timed out.");
assert_eq!(res,Ok(ActionKind::Quit));
let _ = tr.recv_timeout(Duration::from_millis(180)).expect("attempt to receive on quited timed out.");
let _ = s.send(String::from(""));
}