Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![feature(rustc_private)]
- extern crate rand;
- use rand::{Rng, thread_rng};
- #[derive(Clone, Copy)]
- pub struct Board {
- // 0 is closest to the finish
- slots: [usize; 6],
- }
- impl Board {
- // instantiate with a few pieces per slot
- pub fn new() -> Self {
- Board {
- slots: [2, 2, 2, 2, 2, 2],
- }
- }
- // see the board
- pub fn see(self) {
- self.slots.into_iter().enumerate()
- .for_each(|(i,x)|
- println!("slot {:?}: {:?}",i+1, vec![0; *x]),
- );
- }
- // searches for the highest slot with a piece (farthest from finish)
- // and moves that piece toward the finish with the roll
- // (Iterate high -> low)
- pub fn move_far(&mut self, roll: usize) {
- if self.is_done() { return }
- let mut success = false;
- let mut try = self.slots.len();
- while success == false {
- success = self.move_piece(try, roll);
- try -= 1;
- }
- }
- // searches for the lowest slot with a piece (close to finish)
- // starting with the # of the roll. (eg roll 4: search slot 4)
- // (Iterate low -> high)
- // if there are no more slots higher, then go lower
- pub fn move_close(&mut self, roll: usize) {
- if self.is_done() { return }
- let mut increasing = true;
- let mut success = false;
- let mut try = roll;
- while success == false {
- if try > self.slots.len() {
- increasing = false;
- try = roll - 1;
- }
- success = self.move_piece(try, roll);
- if increasing == true {
- try += 1;
- } else {
- try -= 1;
- }
- }
- }
- // checks if the current roll exactly moves a piece into crib;
- // if not, goes with move_far strategy.
- pub fn move_far_with_check(&mut self, roll: usize) {
- if self.is_done() { return }
- if self.has_piece(roll) {
- self.move_piece(roll, roll);
- } else {
- self.move_far(roll);
- }
- }
- fn has_piece(self, position: usize) -> bool {
- self.slots[position - 1] > 0
- }
- fn move_piece(&mut self, position: usize, roll: usize) -> bool {
- if self.has_piece(position) {
- // println!("there is a piece in this position");
- self.slots[position - 1] -= 1;
- if position <= roll {
- // println!("this piece goes to the crib");
- } else {
- // println!("there is a spot for it to move to");
- self.slots[position - roll - 1] += 1;
- }
- return true
- }
- return false
- }
- fn is_done(self) -> bool {
- let sum = self.slots.into_iter().fold(0,|a, &b| a + b);
- sum == 0
- }
- }
- fn main() {
- let mut cathie_scores = Vec::new();
- let mut harry_scores = Vec::new();
- let mut albert_scores = Vec::new();
- for _ in 0..20 {
- let mut cathie = Board::new();
- let mut harry = Board::new();
- let mut albert = Board::new();
- let mut cathie_counter = 0;
- let mut harry_counter = 0;
- let mut albert_counter = 0;
- while !(cathie.is_done() && harry.is_done() && albert.is_done()) {
- let roll = roll_die();
- // println!("roll: {:?}", roll);
- if !cathie.is_done() {
- cathie.move_close(roll);
- // println!("cathie: ");
- // cathie.see();
- cathie_counter += 1;
- }
- if !harry.is_done() {
- harry.move_far(roll);
- // println!("harry: ");
- // harry.see();
- harry_counter += 1;
- }
- if !albert.is_done() {
- albert.move_far_with_check(roll);
- // println!("albert: ");
- // albert.see();
- albert_counter += 1;
- }
- }
- cathie_scores.push(cathie_counter);
- harry_scores.push(harry_counter);
- albert_scores.push(albert_counter);
- }
- // println!("cathie scores: {:?}", cathie_scores);
- // println!("harry scores: {:?}", harry_scores);
- // println!("albert scores: {:?}", albert_scores);
- println!("cathie average: {:?}", average(cathie_scores));
- println!("harry average: {:?}", average(harry_scores));
- println!("albert average: {:?}", average(albert_scores));
- }
- fn average(list: Vec<usize>) -> f64 {
- list.iter().fold(0,|a, &b| a + b) as f64 / (list.len() as f64)
- }
- // rolls between 1 and 6 (inclusive)
- fn roll_die() -> usize {
- let mut rng = thread_rng();
- rng.gen_range(1, 7)
- }
Add Comment
Please, Sign In to add comment