rust/hedgewars-server/src/server/handlers/common.rs
changeset 14415 06672690d71b
parent 14374 e5db279308d7
child 14457 98ef2913ec73
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/hedgewars-server/src/server/handlers/common.rs	Mon Dec 10 22:44:46 2018 +0100
@@ -0,0 +1,73 @@
+use crate::{
+    server::{actions::Action, core::HWServer},
+    protocol::messages::{
+        HWProtocolMessage::{self, Rnd}, HWServerMessage::{self, ChatMsg},
+    }
+};
+use rand::{self, Rng, thread_rng};
+
+pub fn rnd_reply(options: &[String]) -> HWServerMessage {
+    let mut rng = thread_rng();
+    let reply = if options.is_empty() {
+        (*rng.choose(&["heads", "tails"]).unwrap()).to_owned()
+    } else {
+        rng.choose(&options).unwrap().clone()
+    };
+
+    ChatMsg {
+        nick: "[random]".to_owned(),
+        msg: reply.clone(),
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::protocol::messages::HWServerMessage::ChatMsg;
+    use crate::server::actions::{
+        Action::{self, Send}, PendingMessage,
+    };
+
+    fn reply2string(r: HWServerMessage) -> String {
+        match r {
+            ChatMsg { msg: p, .. } => String::from(p),
+            _ => panic!("expected a ChatMsg"),
+        }
+    }
+
+    fn run_handle_test(opts: Vec<String>) {
+        let opts2 = opts.clone();
+        for opt in opts {
+            while reply2string(rnd_reply(&opts2)) != opt {}
+        }
+    }
+
+    /// This test terminates almost surely.
+    #[test]
+    fn test_handle_rnd_empty() {
+        run_handle_test(vec![])
+    }
+
+    /// This test terminates almost surely.
+    #[test]
+    fn test_handle_rnd_nonempty() {
+        run_handle_test(vec!["A".to_owned(), "B".to_owned(), "C".to_owned()])
+    }
+
+    /// This test terminates almost surely (strong law of large numbers)
+    #[test]
+    fn test_distribution() {
+        let eps = 0.000001;
+        let lim = 0.5;
+        let opts = vec![0.to_string(), 1.to_string()];
+        let mut ones = 0;
+        let mut tries = 0;
+
+        while tries < 1000 || ((ones as f64 / tries as f64) - lim).abs() >= eps {
+            tries += 1;
+            if reply2string(rnd_reply(&opts)) == 1.to_string() {
+                ones += 1;
+            }
+        }
+    }
+}