Package playball.gameEngine

Source Code of playball.gameEngine.Game

package playball.gameEngine;

import playball.gameEngine.containers.Pitcher;
import playball.gameEngine.containers.Batter;
import playball.gameEngine.containers.Team;

/**
* The Game class initializes a baseball game between two specified teams and
* provides the methods to simulate the game.
*
* @author
*     Sam Jones (samjones1986@gmail.com)
**/
public class Game
{
    /** the visiting team **/
    private Team visitor;
   
    /** the home team **/
    private Team home;
   
    /** the number of runs scored by the visiting team */
    private int visitorScore;
   
    /** the number of runs scored by the home team */
    private int homeScore;
   
    /** the spot in the order of the next batter from the visiting team **/
    private int visitorOrderSpot;
   
    /** the spot in the order of the next batter from the home team **/
    private int homeOrderSpot;
   
    /** the current inning **/
    private int inning;
   
    /** the current inning half (0 - away, 1 - home) */
    private int inningHalf;
   
    /** the number of outs in the current inning */
    private int outs;
   
    /** the bases of the diamond, where index 0 is the batter at the plate**/
    private Batter[] bases;
   
    private final double PROB_DP = 0.4466;
   
   
    /**
     * Creates a new instance of Game with the specified home and visiting
     * teams and the game ID.
     *
     * @param id
     *  the ID number of the game, in Retrosheet format
     * @param v
     *  the Team object representing the visiting team
     * @param h
     *  the Team object representing the home team
     **/
    public Game(String id, Team v, Team h)
    {
        visitor = v;
        home = h;
        visitorScore = 0;
        homeScore = 0;
        visitorOrderSpot = 0;
        homeOrderSpot = 0;
        inning = 0;
        //playByPlay = new Scoresheet(id, v, h);
    }
   
    /**
     * Plays a baseball game between the two teams.
     *
     * @return
     *  the score of the game, where [0] is the visiting team's score and [1]
     *  is the home team's score
     */
    public int[] playGame()
    {
        System.out.println("Playing game");
       
        //loops for each inning of the game
        //normally stops after the 9th inning, but continues if a tie game
        for (inning = 1; inning <= 9 || scoreIsTied(); inning++)
        {  
            playHalfInning(0);
           
            //used for the bottom of the inning
            //if the inning is 9th or later, checks to see if the score is tied
            //or the home team is losing
            if (inning < 9 || homeIsLosing() || scoreIsTied())
                playHalfInning(1);
        }
       
        int score[] = {visitorScore, homeScore};
        return score;
    }
   
   
    /**
     * Gets the game's visiting team.
     *
     * @return
     *      a Team object representing the visiting team
     **/
    public Team getVisitorTeam()
    {
        return visitor;
    }
   
   
    /**
     * Gets the game's home team.
     *
     * @return
     *      a Team object representing the home team
     **/
    public Team getHomeTeam()
    {
        return home;
    }
   
  
    /**
     * Gets the visiting team's runs.
     *
     * @return
     *      the visiting team's score for the game
     **/
    public int getVisitorScore()
    {
        return visitorScore;
    }
   
   
    /**
     * Gets the home team's runs.
     *
     * @return
     *      the home team's score for the game
     **/
    public int getHomeScore()
    {
        return homeScore;
    }
   
   
    /**
     * Gets the current inning.
     *
     * @return
     *      the current inning of the game
     **/
    public int getInning()
    {
        return inning;
    }
   
   
    /**
     * Determine whether the game is tied or not.
     *
     * @return
     *      true if the game is tied, false otherwise
     **/
    private boolean scoreIsTied()
    {
        return (visitorScore == homeScore);
    }
   
   
    /**
     * Determine whether the home team is losing.
     *
     * @return
     *      true if the home team is losing, false otherwise
     **/
    private boolean homeIsLosing()
    {
        return (visitorScore > homeScore);
    }
   
   
    /**
     * Play half of an inning.
     *
     * @param half
     *  the half of the inning to play; 0 for top, 1 for bottom
     * @return
     *  the number of runs scored in the half inning
     **/
    private void playHalfInning(int half)
    {
        outs = 0;
        inningHalf = half;
        bases = new Batter[4];
       
        int outcome; //outcome of an at bat
        char ballType = ' '; //the batted ball type (for an out)
       
        //only executes if there are less than 3 outs, and the visiting team is
        //batting, or if the home team still has the opportunity to bat, such as
        //before the 9th inning, or if the home team is losing or the game is
        //tied in the 9th inning or later
        while (outs < 3 && continueInning())
        {
            System.out.println("Inn:" + inning + " Half:" + half +
                               " Outs:" + getOuts() +
                               " Home:" + homeScore + " Vis:" + visitorScore);
            System.out.println("1st: " + getRunnerOnFirst());
            System.out.println("2nd: " + getRunnerOnSecond());
            System.out.println("3rd: " + getRunnerOnThird());

            if (willBeRunning(1))
            {
                System.out.println(getRunnerOnFirst() +
                                   " attempts to steal 2nd");
               
                attemptSteal(1);
               
                if (getRunnerOnSecond() == null)
                    System.out.println("Steal unsuccessful");
                else
                    System.out.println("Steal successful");
                System.out.println("--------------------------------------");
            }
            else
            {
                Batter nextBatter;
                Pitcher thePitcher;

                if (half == 0)
                {
                    nextBatter = nextVisitorBatter();
                    thePitcher = (Pitcher) home.getFielder(1);
                }
                else
                {
                    nextBatter = nextHomeBatter();
                    thePitcher = (Pitcher) visitor.getFielder(1);
                }

                //AtBat matchup = new AtBat(nextBatter, thePitcher);
                AtBat matchup = new AtBat(nextBatter,thePitcher);
                sendBatterUp(nextBatter);
                matchup.generateAtBat();
                outcome = matchup.getOutcome();
                if (outcome == 2)
                    ballType = matchup.getBattedBallType();
                else
                    ballType = ' ';
               
                System.out.println(nextBatter + " hits a " +
                                   outcome + "/" + ballType +
                                   " off of " + thePitcher);
               
                advanceRunners(outcome, ballType);
               
                System.out.println("--------------------------------------");
            }
        }
    }


    /**
     * Retrieves the next batter on the visiting team.
     *
     * @return
     *  the batter on the visiting team due up next
     */
    private Batter nextVisitorBatter()
    {
        visitorOrderSpot++;
        if (visitorOrderSpot > 9)
            visitorOrderSpot = 1;
        return visitor.getBatter(visitorOrderSpot);
    }
   
   
    /**
     * Retrieves the next batter on the home team.
     *
     * @return
     *  the batter on the home team due up next
     */
    private Batter nextHomeBatter()
    {
        homeOrderSpot++;
        if (homeOrderSpot > 9)
            homeOrderSpot = 1;
        return home.getBatter(homeOrderSpot);
    }
   
    /**
     * Gets the batter currently up to bat.
     * @return
     *   the batter at the plate
     */
    public Batter getBatterUp()
    {
        return bases[0];
    }

    /**
     * Gets the runner currently on first base.
     * @return
     *   the runner on first
     */
    public Batter getRunnerOnFirst()
    {
        return bases[1];
    }

    /**
     * Gets the runner currently on second base.
     * @return
     *   the runner on second
     */
    public Batter getRunnerOnSecond()
    {
        return bases[2];
    }

    /**
     * Gets the runner currently on third base.
     * @return
     *   the runner on third
     */
    public Batter getRunnerOnThird()
    {
        return bases[3];
    }
   
    /**
     * Gets the number of outs in the current inning.
     * @return
     *   the current number of outs
     */
    public int getOuts()
    {
        return outs;
    }

    /**
     * Places the specified batter at the plate to be ready for the outcome of
     * an at bat.
     * @param b
     *   the Batter to send to the plate
     */
    public void sendBatterUp(Batter b)
    {
        bases[0] = b;
    }
   
        /**
     * Advance the runners on the diamond according to the outcome of an at bat
     * and the type of the batted ball, if any. Returns the number of runs
     * scored on the play.
     *
     * @param action
     *      the integer representation of the outcome of an at bat:
     * @param battedBallType
     *      the type of the batted ball, mostly used for outs
     *      'F' - fly ball
     *      'L' - line drive
     *      'P' - pop up
     *      'G' - ground ball
     *      ' ' - no batted ball or no type specified
     * @throws IllegalArgumentException
     *      indicates that action has been passed an illegal value
     **/
    public void advanceRunners(int action, char battedBallType)
    {
        if (action >= 14 && action <= 16) //batter walks or is hit by pitch
        {
            if (bases[1] != null)
            {
                if (bases[2] != null)
                {
                    if (bases [3] != null)
                    {
                        this.scoreRun();
                        bases[3] = null;
                    }
                   
                    bases[3] = bases[2];
                    bases[2] = null;
                }
               
                bases[2] = bases[1];
                bases[1] = null;
            }
           
            bases[1] = bases[0];
            bases[0] = null;
        }
        else if (action == 20) //batter singles
        {
            if (bases[3] != null && continueInning())
            {
                this.scoreRun();
                bases[3] = null;
            }
           
            if (bases[2] != null && continueInning())
            {
                this.scoreRun();
                bases[2] = null;
            }
           
            if (bases[1] != null)
            {
                bases[2] = bases[1];
                bases[1] = null;
            }
           
            bases[1] = bases[0];
            bases[0] = null;
        }
        else if (action == 21) //batter doubles
        {
            if(bases[3] != null && continueInning())
            {
                this.scoreRun();
                bases[3] = null;
            }
            if(bases[2] != null && continueInning())
            {
                this.scoreRun();
                bases[2] = null;
            }
            if(bases[1] != null)
            {
                bases[3] = bases[1];
                bases[1] = null;
            }
            bases[2] = bases[0];
            bases[0] = null;
        }
        else if (action == 22) //batter triples
        {
            if(bases[3] != null && continueInning())
            {
                this.scoreRun();
                bases[3] = null;
            }

            if(bases[2] != null && continueInning())
            {
                this.scoreRun();
                bases[2] = null;
            }

            if(bases[1] != null && continueInning())
            {
                this.scoreRun();
                bases[1] = null;
            }

            bases[3] = bases[0];
            bases[0] = null;
        }
        else if (action == 23) //batter homers
        {
            if(bases[3] != null)
            {
                this.scoreRun();
                bases[3] = null;
            }

            if(bases[2] != null)
            {
                this.scoreRun();
                bases[2] = null;
            }

            if(bases[1] != null)
            {
                this.scoreRun();
                bases[1] = null;
            }

           
            this.scoreRun();
           
            bases[0] = null;
        }
        else if (action == 3) //batter strikes out
        {
            bases[0] = null;
            outs++;
        }
        else if (action == 2 && battedBallType == 'F') //batter flies out
        {
            if (outs < 2 && bases[3] != null) //possbile sacrifice fly
            {
                bases[3] = null;
                this.scoreRun();
            }

            bases[0] = null;
            outs++;
        }
        else if (action == 2 && battedBallType == 'G') //batter grounds out
        {
            if (bases[1] == null && bases[2] == null && bases[3] == null)
            {
                bases[0] = null;
                outs++;
            }
            else if (bases[1] != null) //possible double play
            {
                if (bases[2] != null)
                {
                    if (bases[3] != null) //bases loaded
                    {
                        bases[3] = bases[2];
                        bases[2] = bases[1];
                        bases[1] = bases[0];
                        bases[0] = null;
                        outs++;
                    }
                    else //runners on 1st and 2nd
                    {
                        if (Math.random() < PROB_DP) //a double play is turned
                        {
                            bases[3] = bases[2];
                            bases[2] = null;
                            bases[1] = null;
                            bases[0] = null;

                            outs++;
                            if (outs < 3)
                                outs++;
                        }
                        else //double play is unsuccessful
                        {
                            bases[3] = bases[2];
                            bases[2] = null;
                            bases[1] = bases[0];
                            bases[0] = null;

                            outs++;
                        }
                    }
                }
                else //runner on 1st or runners on 1st and 3rd
                {
                    if (Math.random() < PROB_DP) //a double play is turned
                    {
                        bases[2] = null;
                        bases[1] = null;
                        bases[0] = null;

                        outs++;
                        if (outs < 3)
                            outs++;
                    }
                    else //double play is unsuccessful
                    {
                        bases[2] = null;
                        bases[1] = bases[0];
                        bases[0] = null;

                        outs++;
                    }
                }
            }
            else //no runner on 1st, but not bases empty
            {
                bases[0] = null;
                outs++;
            }
        }
        else if (action == 2) //batter is out some other way
        {
             bases[0] = null;
             outs++;
        }
        else //action has been passed an illegal value
        {
            String msg = "action " + action + " is an illegal argument";
            throw new IllegalArgumentException(msg);
        }
    }
   
    /**
     * Determines whether to continute the inning or not.
     * @return
     *   true if the inning should continue, false otherwise
     */
    private boolean continueInning()
    {
        return inningHalf == 0 || inning < 9 || visitorScore >= homeScore;
    }
   
    /**
     * Makes the runner on the specified base attempt to steal.
     *
     * @param runner
     *  the base the runner that would like to steal is on
     */
    public void attemptSteal(int runner)
    {
        int baseToSteal = runner + 1;

        if ((runner == 1 || runner == 2) &&
                bases[runner] != null && bases[baseToSteal] == null)
        {
            if (Math.random() < (bases[runner].getStolenBaseSuccessRate()))
            {
                bases[baseToSteal] = bases[runner];
                bases[runner] = null;
            }
            else
            {
                bases[runner] = null;
                outs++;
            }
        }
    }

    /**
     * Determines whether or not the runner on the specified base will be
     * running.
     *
     * @param runner
     *  the base that is occupied by the potential base stealer
     * @return
     *  true if the runner will attempt to steal, false if not
     */
    public boolean willBeRunning(int runner)
    {
        int baseToSteal = runner + 1;

        if ((runner == 1 || runner == 2) &&
                bases[runner] != null && bases[baseToSteal] == null)
        {
            return Math.random() < bases[runner].getStolenBaseAttemptRate();
        }
        else
        {
            return false;
        }
    }
   
    /**
     * Tally a run scored for the current batting team.
     */
    private void scoreRun() {
        if (inningHalf == 0) {
            this.visitorScore++;
        }
        else {
            this.homeScore++;
        }
    }
}
TOP

Related Classes of playball.gameEngine.Game

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.