1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
//! Small and simple round robin tournament implementation. //! //! Provides an interface for passing the number of players to participate in the tournament //! and gives a list of of possible rounds. In each round there is a list ofindividual unique pairs. //! Each player is represented by a u32 number. //! # Example //! ``` //! use round_robin_tournament::round_robin_tournament::draw; //! //! let tournament: Vec<Vec<(u32, u32)>> = draw(10); //! // First round with 5 matches //! let first_round = tournament.first().unwrap(); //! // First match with player id 0 against player id 9 //! let first_match = first_round.first().unwrap(); //! //! ``` //! pub mod round_robin_tournament { /// Implementation of the round robin tournament algorithm. /// /// For a given `number_of_players` it return the pairs and rounds. /// For an odd number of players, the algorithm calculates with `number_of_players` + 1. /// So you have to make sure that the player who plays against the highest number has a bye. /// # Example /// ``` /// use round_robin_tournament::round_robin_tournament::draw; /// let tournament: Vec<Vec<(u32, u32)>> = draw(10); /// /* /// [(0, 9), (1, 8), (2, 7), (3, 6), (4, 5)] /// [(1, 9), (2, 0), (3, 8), (4, 7), (5, 6)] /// [(2, 9), (3, 1), (4, 0), (5, 8), (6, 7)] /// [(3, 9), (4, 2), (5, 1), (6, 0), (7, 8)] /// [(4, 9), (5, 3), (6, 2), (7, 1), (8, 0)] /// [(5, 9), (6, 4), (7, 3), (8, 2), (0, 1)] /// [(6, 9), (7, 5), (8, 4), (0, 3), (1, 2)] /// [(7, 9), (8, 6), (0, 5), (1, 4), (2, 3)] /// [(8, 9), (0, 7), (1, 6), (2, 5), (3, 4)] /// */ /// ``` pub fn draw(number_of_players: u32) -> Vec<Vec<(u32, u32)>> { let nop = if number_of_players % 2 == 0 { number_of_players } else { number_of_players + 1 }; let mut players: Vec<u32> = (0..nop).collect(); let mut rounds: Vec<Vec<(u32, u32)>> = Vec::new(); let fixed_player = players.pop().unwrap().clone(); for i in 0..(nop - 1) { let mut pairs = Vec::new(); if i != 0 { players.rotate_left(1) } let mut players_clone = players.clone(); players_clone.rotate_left(1); let first = players_clone.pop().unwrap(); pairs.push((first.clone(), fixed_player.clone())); let split_list = players_clone.split_at_mut(((nop - 2) / 2) as usize); split_list.1.reverse(); for j in 0..((nop - 2) / 2) { let a: Option<&u32> = split_list.0.get(j as usize); let b: Option<&u32> = split_list.1.get(j as usize); if a.is_some() && b.is_some() { pairs.push((a.unwrap().clone(), b.unwrap().clone())) } } rounds.push(pairs) } rounds } } #[cfg(test)] mod tests { use crate::round_robin_tournament::draw; fn tournament_test_data() -> Vec<Vec<(u32, u32)>> { vec![ vec![(0, 9), (1, 8), (2, 7), (3, 6), (4, 5)], vec![(1, 9), (2, 0), (3, 8), (4, 7), (5, 6)], vec![(2, 9), (3, 1), (4, 0), (5, 8), (6, 7)], vec![(3, 9), (4, 2), (5, 1), (6, 0), (7, 8)], vec![(4, 9), (5, 3), (6, 2), (7, 1), (8, 0)], vec![(5, 9), (6, 4), (7, 3), (8, 2), (0, 1)], vec![(6, 9), (7, 5), (8, 4), (0, 3), (1, 2)], vec![(7, 9), (8, 6), (0, 5), (1, 4), (2, 3)], vec![(8, 9), (0, 7), (1, 6), (2, 5), (3, 4)], ] } #[test] fn round_robin_10_player() { let result = draw(10); result.iter().for_each(|r|{println!("{:?}", r);}); assert_eq!(result, tournament_test_data()); } #[test] fn round_robin_9_player() { let result = draw(9); assert_eq!(result, tournament_test_data()); } }