Keeping score in a baseball game simulation - Is Hash Map the way to go?

I have code that simulates a 27 out baseball game for one team batting and one team pitching. If I wanted to keep score for the team that is batting, is Hash Map the best way to do so?

use rand::Rng;
use std::collections::HashMap;

#[derive(Debug, Copy, Clone)]

pub enum PitchResult {
    Ball,
    Strike,
    Out,
    Single,
    Double,
    Triple,
    HomeRun,

}


impl PitchResult {
    pub fn random() -> Self {
        
        if rand::thread_rng().gen_range(0..3) == 0 {
            PitchResult::Ball
        }
        else if rand::thread_rng().gen_range(0..3) == 1 {
            PitchResult::Strike
        }
        else if rand::thread_rng().gen_range(0..3) == 2 {
            PitchResult::Single
             }
        else if rand::thread_rng().gen_range(0..3) == 2 {
            PitchResult::Double
        }
        else if rand::thread_rng().gen_range(0..3) == 2 {
            PitchResult::Triple
             }
        else if rand::thread_rng().gen_range(0..3) == 2 {
            PitchResult::HomeRun
        } else {
            PitchResult::Out
        }
      
        

    }
}

fn main() {
    
    println!("*****Game Start*****");
    let mut at_bat = 0;
    'counting_up: loop {
    let mut balls = 0;
    let mut strikes = 0;
    let mut single = 0;
    let mut double = 0;
    let mut triple = 0;
    let mut homerun = 0;
    let mut outs = 0;
    

    let mut scores = HashMap::new();
    scores.insert(String::from("Team1"), 0);
    scores.insert(String::from("Team2"), 0);
    //let team_name1 = String::from("Team1");
    //let team_name2 = String::from("Team2");
    //let score = scores.get(&team_name1, &team_name2);

    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }


      

    while balls < 4 && strikes < 3 && outs == 0 && single == 0 && double == 0 && triple == 0 && homerun == 0 && at_bat < 27 {
        // println!("At Bat = {}", at_bat);
        let pitch = PitchResult::random();
        match pitch {
            PitchResult::Ball => balls += 1,
            PitchResult::Strike => strikes += 1,
            PitchResult::Single => single += 1,
            PitchResult::Double => double += 1,
            PitchResult::Triple => triple += 1,
            PitchResult::HomeRun => homerun += 1,
            PitchResult::Out => outs += 1,
    

        }
        
        println!("The pitch is a: {:?}", pitch);

    if outs > 0 {
        
        at_bat += 1;
        println!("Total Outs = {}", at_bat);
        if at_bat < 27 {
        println!("*****New Batter*****");
        }
        continue
    }

    if single > 0 {
        println!("*****New Batter*****");
        continue
    }

     if double > 0 {
        println!("*****New Batter*****");
        continue
    }

    if triple > 0 {
        println!("*****New Batter*****");
        continue
    }

     if homerun > 0 {
        println!("*****New Batter*****");
        continue
    }
    




    if strikes == 3 {
        println!("Strike Out!");
        at_bat += 1;
        println!("Total Outs = {}", at_bat);
        println!("*****New Batter*****");
        continue
    }

    if balls == 4 {
        println!("Batter Walked!");
        println!("*****New Batter*****");
        continue
    }

    if balls > 0 || balls < 4 || strikes > 0 || strikes < 3 {
        println!("The count is: {} - {}", balls, strikes);
    }

     if balls == 3 && strikes == 2 {
        println!("Full Count!");
    }
 
     if balls == 3 && strikes == 0 {
        println!("Hitter's Count!");
    }

     if balls == 0 && strikes == 2 {
        println!("Pitcher's Count!");
    }

    }      


    if at_bat == 27 {
        println!("That's the Ballgame Folks!");
        break 'counting_up;
    }

}
    
}

1 Like

Please format your code so it is readable.

Also, is there a question or particular piece of code you are referring to? It's unclear what you are actually asking here or the context behind the question[1].


  1. For example, if you had two algorithms and wanted to know the "better" one, you would need to think about the expected range/magnitude of inputs and how it is being used. You would also need to think about whether performance is a concern or if you just want something that is simple to implement/use. ↩︎

2 Likes

It would depend. If you need to lookup teams by name and name-only, then HashMap is a good choice. On the other hand, if you could look them up by index, then Vec is a better option.
Since you are likely to have only a small number of teams, you could even use a stack allocated map like st-map.

1 Like

The most direct definition would probably look like:

struct Game {
  // Games always have two teams, and two teams only.
  teams: [GameTeam; 2],
}

struct GameTeam {
  name: String,
  score: u32,
}

but you could have plenty of other structures (home and away fields, for example).

In general I wouldn't recommend using Map types with user-displayed (and especially not user-controlled) values: it makes a lot of things tougher than they should be. In this case, to be clear, it doesn't realistically matter at all, but consider how you might handle the equivalents of translations for the names, editing them during the game, some joker naming the two teams the same name, how you handle all the weird things Unicode can do like normalization forms, locale sensitive casing rules, and lots more insanity you don't want to have to handle for just telling which team is which!

For keys, prefer using an id that is automatically generated integer or ASCII (hexadecimal or base64, for example), where possible.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.