Skip to main content
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

A long long time ago I asked this questionthis question which has since garnered about one thousand views. Now for something new.

A long long time ago I asked this question which has since garnered about one thousand views. Now for something new.

A long long time ago I asked this question which has since garnered about one thousand views. Now for something new.

deleted 58 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Self-playing Baseball Gamegame -- An es6 update

###A loongA long long time ago I asked this question which has since garnered about one thousand views.


#Now Now for something new

The demo for what I have is located here: http://jsfiddle.net/maniator/ueceeq7k/28/

I am generally happy with what I have built (although I did not implement all of the visuals (yet) of the original).

The demo for what I want to know if therehave is some improvements to my hitting algorithm that can be made, and maybe some suggestions of how tolocated here. I am generally happy with what I have built (although I did not implement other fieldersall of the visuals (aside fromyet) of the pitcher that is already writtenoriginal).

The javascript codeI want to know if there is as follows:some improvements to my hitting algorithm that can be made, and maybe some suggestions of how to implement other fielders (aside from the pitcher that is already written).

Self-playing Baseball Game -- An es6 update

###A loong long time ago I asked this question which has since garnered about one thousand views.


#Now for something new

The demo for what I have is located here: http://jsfiddle.net/maniator/ueceeq7k/28/

I am generally happy with what I have built (although I did not implement all of the visuals (yet) of the original).

I want to know if there is some improvements to my hitting algorithm that can be made, and maybe some suggestions of how to implement other fielders (aside from the pitcher that is already written)

The javascript code is as follows:

Self-playing Baseball game -- An es6 update

A long long time ago I asked this question which has since garnered about one thousand views. Now for something new.

The demo for what I have is located here. I am generally happy with what I have built (although I did not implement all of the visuals (yet) of the original).

I want to know if there is some improvements to my hitting algorithm that can be made, and maybe some suggestions of how to implement other fielders (aside from the pitcher that is already written).

Tweeted twitter.com/StackCodeReview/status/719628747650002944
deleted 32 characters in body
Source Link
Naftali
  • 1.1k
  • 2
  • 13
  • 33

The demo for what I have is located here: http://jsfiddle.net/maniator/ueceeq7k/27/http://jsfiddle.net/maniator/ueceeq7k/28/

const logger = ((logArea, logDelay = 0) => {
    const playArea = document.getElementById(logArea);
    return {
        delay: logDelay,
        log(...args) {
            let div = document.createElement('div');

        
      // Can see the result in the console
            console.log(...args);

            setTimeout(() => {
                // append to the top of the log
                playArea.insertBefore(div, playArea.firstChild);
                div.textContent = args.join(', ')
            }, this.delay);

            this.delay += logDelay;
        },
        logPad(...args) {
            this.log();
            this.log(...args);
        }
    };
})('playArea', 120);

const Team = (() => {
    const numberOfPlayers = 9;

    return class Team {
        constructor(name) {
            this.name = name;
            this.players = [];
            this.listeners = [];
            this.playerIndex = 0;
            this.score = 0;
            this.generatePlayers();
        }

        toString() {
            return this.name;
        }

        gainRun() {
            this.score++;
            logger.log(`${this} now have ${this.score} runs`);
        }

        generatePlayers() {
            for (let i = 0; i < numberOfPlayers; ++i) {
                this.players.push(new Player(`${this} Player ${i + 1}`, this));
            }

            this.pitcher = new Pitcher(`${this} Pitcher`, this);
        }

        nextPlayer() {
            this.playerIndex %= numberOfPlayers;

            let nextPlayer = this.players[this.playerIndex++];

            logger.log(`${nextPlayer} is up to bat`);

            return nextPlayer;
        }

        pitchTo(otherTeam) {
            let outs = 0;
            while (outs < 3) {
                let nextPlayer = otherTeam.nextPlayer();
                let strikes = 0;
                let balls = 0;

                while (strikes < 3 && balls < 4) {
                    let pitch = this.pitcher.pitch();
                    let hit = nextPlayer.acceptPitch(strikes, balls);

                    if (hit.out) {
                        outs++;

                        logger.log(`${nextPlayer} hit the ball!`);
                        logger.log(`${nextPlayer} hit a ${hit.name}`);
                        break;
                    }

                    if (hit.bases === 0) {
                        if (hit.strike) {
                            strikes++;
                            logger.log(`${nextPlayer} swung and missed`);
                        } else {
                            if (pitch.strike) {
                                strikes++;
                            } else {
                                balls++;
                            }
                            logger.log(`${nextPlayer} waited and got a ${pitch.name}`);
                        }
                    } else {
                        logger.log(`${nextPlayer} hit the ball!`);
                        this.trigger('Hit', nextPlayer, hit);
                        logger.log(`${nextPlayer} got a ${hit.name}`);
                        break;
                    }
                }

                if (strikes >= 3) {
                    outs++;
                    logger.log(`${nextPlayer} struck out`);
                } else if (balls >= 4>=4) {
                    logger.log(`${nextPlayer} walked`);
                    this.trigger('Hit', nextPlayer, {
                        bases: 1,
                    });
                }
            }
        }

        addListener(object) {
            if (!!object.trigger) {
                this.listeners.push(object);
            }
        }

        trigger() {
            this.listeners.forEach((listener) => listener.trigger(...arguments))
        }
    };
})();

class Player {
    constructor(name, team) {
        this.name = name;
        this.team = team;
    }

    toString() {
        return this.name;
    }

    acceptPitch(strikes = 0, balls = 0) {
        const random = Math.floor(Math.random() * 1000);
        const swingRate = 500 - (75 * strikes) + (30 * balls);

        if (random < swingRate) {
            return {
                name: 'swing and a miss',
                bases: 0,
                out: false,
                strike: true,
            };
        } else if (random < 880) { // wait for the pitch or hit into an out
            if (random > 830) {
                return {
                    name: 'fly out',
                    bases: 0,
                    out: true,
                };
            } else if (random > 810) {
                return {
                    name: 'ground out',
                    bases: 0,
                    out: true,
                };
            }

            return {
                name: 'wait',
                bases: 0,
                out: false,
            };
        } else if (random <= 1000) { // hit the ball
            if (random > 940 && random < 970) {
                return {
                    name: 'double',
                    bases: 2,
                    out: false,
                };
            }
            else if (random >= 970 && random < 995) {
                return {
                    name: 'triple',
                    bases: 3,
                    out: false,
                };
            }
            else if (random >= 995) {
                return {
                    name: 'homerun',
                    bases: 4,
                    out: false,
                };
            } else {
                return {
                    name: 'single',
                    bases: 1,
                    out: false,
                };
            }
        }
    }
}
 ;

class Pitcher extends Player {
    static get pitchTypes() {
        // @todo math this SH*T up
        return [{
            name: 'strike',
            strike: true,
        }, {
            name: 'ball',
            strike: false,
        }, {
            name: 'strike',
            strike: true,
        },];
    }

    pitch() {
        const types = Pitcher.pitchTypes;
        const random = Math.floor(Math.random() * (types).length);
        logger.log(`${this} threw the ball`);
        return types[random];
    }
}
 ;

const Stadium = ((diamondArea) => {
    const diamondDiv = document.getElementById(diamondArea);
    let firstBase = false,
        secondBase = false,
        thirdBase = false,
        home = false;

    return class Stadium {
        constructor(a, b) {
            // @todo checks that a and b are team objects
            this.teams = [a, b];
        }

        set firstBase(player) {
            if (firstBase && player) {
                logger.log(`${firstBase} ran to second`);
                this.secondBase = firstBase;(firstBase);
            }
            firstBase = player;
        }

        set secondBase(player) {
            if (secondBase && player) {
                logger.log(`${secondBase} ran to third`);
                this.thirdBase = secondBase;(secondBase);
            }
            secondBase = player;
        }

        set thirdBase(player) {
            if (thirdBase && player) {
                logger.log(`${thirdBase} ran home`);
                this.home = thirdBase;(thirdBase);
            }
            thirdBase = player;
        }

        set home(player) {
            player.team.gainRun();
        }

        single(player) {
            this.firstBase = player;(player);
            logger.log(`${player} ran to first base`);
        }

        double(player) {
            this.single(player);
            this.secondBase = player;(player);
            this.firstBase = false;(false);
            logger.log(`${player} ran to second base`);
        }

        triple(player) {
            this.double(player);
            this.thirdBase = player;(player);
            this.secondBase = false;(false);
            logger.log(`${player} ran to third base`);
        }

        homerun(player) {
            this.triple(player);
            this.home = player;(player);
            this.thirdBase = false;(false);
            logger.log(`${player} ran to home base`);
        }

        get baseTypes() {
            return [this.homerun, this.single, this.double, this.triple];
        }

        clear() {
            firstBase = secondBase = thirdBase = false;

            return this;
        }

        playGame(innings) {
            let extraInnings = 0;
            let [teamA, teamB] = this.teams;
            logger.log(`${innings} inning game!`);
            this.listenToTeamActions();
            for (let i = 1; i <= innings; ++i) {
                logger.logPad(`Playing inning ${i} of ${innings}`);
                this.playInning(i);
            }

            while (teamA.score === teamB.score) {
                extraInnings++;
                logger.logPad(`EXTRA INNINGS!`);
                logger.logPad(`Score: ${teamA}: ${teamA.score} to ${teamB}: ${teamB.score}`);

                this.playInning(`EXTRA ${extraInnings}`);
            }

            logger.logPad(`GAME OVER${extraInnings ? ` WITH ${extraInnings} EXTRA INNINGS!` : '!'}`);
            logger.logPad(`Score: ${teamA}: ${teamA.score} to ${teamB}: ${teamB.score}`);
        }

        playInning(index) {
            let [teamA, teamB] = this.teams;

            logger.logPad(`${teamB} are up to bat in inning ${index}`);
            teamA.pitchTo(teamB);

            this.clear();

            logger.logPad(`${teamA} are up to bat in inning ${index}`);
            teamB.pitchTo(teamA);

            this.clear();
        }

        listenToTeamActions() {
            let [teamA, teamB] = this.teams;

            teamA.addListener(this);
            teamB.addListener(this);
        }

        trigger(event, ...args) {
            // @todo make first letter of event uppercase
            if (!!this[`on${event}`]) {
                this[`on${event}`](...args);
            }
        }

        onHit(player, type) {
            const baseTypes = this.baseTypes;
            const numberOfBases = type.bases % 4;

            baseTypes[numberOfBases].bind(this)(player);
        }
    };
})('diamond');

const mets = new Team('Mets');
const yankees = new Team('Yankees');
const citiField = new Stadium(mets, yankees);
console.log(mets, yankees);
citiField.playGame(9);

The demo for what I have is located here: http://jsfiddle.net/maniator/ueceeq7k/27/

const logger = ((logArea, logDelay = 0) => {
    const playArea = document.getElementById(logArea);
    return {
        delay: logDelay,
        log(...args) {
            let div = document.createElement('div');

             // Can see the result in the console
            console.log(...args);

            setTimeout(() => {
                // append to the top of the log
                playArea.insertBefore(div, playArea.firstChild);
                div.textContent = args.join(', ')
            }, this.delay);

            this.delay += logDelay;
        },
        logPad(...args) {
            this.log();
            this.log(...args);
        }
    };
})('playArea', 120);

const Team = (() => {
    const numberOfPlayers = 9;

    return class Team {
        constructor(name) {
            this.name = name;
            this.players = [];
            this.listeners = [];
            this.playerIndex = 0;
            this.score = 0;
            this.generatePlayers();
        }

        toString() {
            return this.name;
        }

        gainRun() {
            this.score++;
            logger.log(`${this} now have ${this.score} runs`);
        }

        generatePlayers() {
            for (let i = 0; i < numberOfPlayers; ++i) {
                this.players.push(new Player(`${this} Player ${i + 1}`, this));
            }

            this.pitcher = new Pitcher(`${this} Pitcher`, this);
        }

        nextPlayer() {
            this.playerIndex %= numberOfPlayers;

            let nextPlayer = this.players[this.playerIndex++];

            logger.log(`${nextPlayer} is up to bat`);

            return nextPlayer;
        }

        pitchTo(otherTeam) {
            let outs = 0;
            while (outs < 3) {
                let nextPlayer = otherTeam.nextPlayer();
                let strikes = 0;
                let balls = 0;

                while (strikes < 3 && balls < 4) {
                    let pitch = this.pitcher.pitch();
                    let hit = nextPlayer.acceptPitch(strikes, balls);

                    if (hit.out) {
                        outs++;

                        logger.log(`${nextPlayer} hit the ball!`);
                        logger.log(`${nextPlayer} hit a ${hit.name}`);
                        break;
                    }

                    if (hit.bases === 0) {
                        if (hit.strike) {
                            strikes++;
                            logger.log(`${nextPlayer} swung and missed`);
                        } else {
                            if (pitch.strike) {
                                strikes++;
                            } else {
                                balls++;
                            }
                            logger.log(`${nextPlayer} waited and got a ${pitch.name}`);
                        }
                    } else {
                        logger.log(`${nextPlayer} hit the ball!`);
                        this.trigger('Hit', nextPlayer, hit);
                        logger.log(`${nextPlayer} got a ${hit.name}`);
                        break;
                    }
                }

                if (strikes >= 3) {
                    outs++;
                    logger.log(`${nextPlayer} struck out`);
                } else if (balls >= 4) {
                    logger.log(`${nextPlayer} walked`);
                    this.trigger('Hit', nextPlayer, {
                        bases: 1,
                    });
                }
            }
        }

        addListener(object) {
            if (!!object.trigger) {
                this.listeners.push(object);
            }
        }

        trigger() {
            this.listeners.forEach((listener) => listener.trigger(...arguments))
        }
    };
})();

class Player {
    constructor(name, team) {
        this.name = name;
        this.team = team;
    }

    toString() {
        return this.name;
    }

    acceptPitch(strikes = 0, balls = 0) {
        const random = Math.floor(Math.random() * 1000);
        const swingRate = 500 - (75 * strikes) + (30 * balls);

        if (random < swingRate) {
            return {
                name: 'swing and a miss',
                bases: 0,
                out: false,
                strike: true,
            };
        } else if (random < 880) { // wait for the pitch or hit into an out
            if (random > 830) {
                return {
                    name: 'fly out',
                    bases: 0,
                    out: true,
                };
            } else if (random > 810) {
                return {
                    name: 'ground out',
                    bases: 0,
                    out: true,
                };
            }

            return {
                name: 'wait',
                bases: 0,
                out: false,
            };
        } else if (random <= 1000) { // hit the ball
            if (random > 940 && random < 970) {
                return {
                    name: 'double',
                    bases: 2,
                    out: false,
                };
            }
            else if (random >= 970 && random < 995) {
                return {
                    name: 'triple',
                    bases: 3,
                    out: false,
                };
            }
            else if (random >= 995) {
                return {
                    name: 'homerun',
                    bases: 4,
                    out: false,
                };
            } else {
                return {
                    name: 'single',
                    bases: 1,
                    out: false,
                };
            }
        }
    }
}
 ;

class Pitcher extends Player {
    static get pitchTypes() {
        // @todo math this SH*T up
        return [{
            name: 'strike',
            strike: true,
        }, {
            name: 'ball',
            strike: false,
        }, {
            name: 'strike',
            strike: true,
        },];
    }

    pitch() {
        const types = Pitcher.pitchTypes;
        const random = Math.floor(Math.random() * (types).length);
        logger.log(`${this} threw the ball`);
        return types[random];
    }
}
 ;

const Stadium = ((diamondArea) => {
    const diamondDiv = document.getElementById(diamondArea);
    let firstBase = false,
        secondBase = false,
        thirdBase = false,
        home = false;

    return class Stadium {
        constructor(a, b) {
            // @todo checks that a and b are team objects
            this.teams = [a, b];
        }

        set firstBase(player) {
            if (firstBase && player) {
                logger.log(`${firstBase} ran to second`);
                this.secondBase = firstBase;
            }
            firstBase = player;
        }

        set secondBase(player) {
            if (secondBase && player) {
                logger.log(`${secondBase} ran to third`);
                this.thirdBase = secondBase;
            }
            secondBase = player;
        }

        set thirdBase(player) {
            if (thirdBase && player) {
                logger.log(`${thirdBase} ran home`);
                this.home = thirdBase;
            }
            thirdBase = player;
        }

        set home(player) {
            player.team.gainRun();
        }

        single(player) {
            this.firstBase = player;
            logger.log(`${player} ran to first base`);
        }

        double(player) {
            this.single(player);
            this.secondBase = player;
            this.firstBase = false;
            logger.log(`${player} ran to second base`);
        }

        triple(player) {
            this.double(player);
            this.thirdBase = player;
            this.secondBase = false;
            logger.log(`${player} ran to third base`);
        }

        homerun(player) {
            this.triple(player);
            this.home = player;
            this.thirdBase = false;
            logger.log(`${player} ran to home base`);
        }

        get baseTypes() {
            return [this.homerun, this.single, this.double, this.triple];
        }

        clear() {
            firstBase = secondBase = thirdBase = false;

            return this;
        }

        playGame(innings) {
            let extraInnings = 0;
            let [teamA, teamB] = this.teams;
            logger.log(`${innings} inning game!`);
            this.listenToTeamActions();
            for (let i = 1; i <= innings; ++i) {
                logger.logPad(`Playing inning ${i} of ${innings}`);
                this.playInning(i);
            }

            while (teamA.score === teamB.score) {
                extraInnings++;
                logger.logPad(`EXTRA INNINGS!`);
                logger.logPad(`Score: ${teamA}: ${teamA.score} to ${teamB}: ${teamB.score}`);

                this.playInning(`EXTRA ${extraInnings}`);
            }

            logger.logPad(`GAME OVER${extraInnings ? ` WITH ${extraInnings} EXTRA INNINGS!` : '!'}`);
            logger.logPad(`Score: ${teamA}: ${teamA.score} to ${teamB}: ${teamB.score}`);
        }

        playInning(index) {
            let [teamA, teamB] = this.teams;

            logger.logPad(`${teamB} are up to bat in inning ${index}`);
            teamA.pitchTo(teamB);

            this.clear();

            logger.logPad(`${teamA} are up to bat in inning ${index}`);
            teamB.pitchTo(teamA);

            this.clear();
        }

        listenToTeamActions() {
            let [teamA, teamB] = this.teams;

            teamA.addListener(this);
            teamB.addListener(this);
        }

        trigger(event, ...args) {
            // @todo make first letter of event uppercase
            if (!!this[`on${event}`]) {
                this[`on${event}`](...args);
            }
        }

        onHit(player, type) {
            const baseTypes = this.baseTypes;
            const numberOfBases = type.bases % 4;

            baseTypes[numberOfBases].bind(this)(player);
        }
    };
})('diamond');

const mets = new Team('Mets');
const yankees = new Team('Yankees');
const citiField = new Stadium(mets, yankees);
console.log(mets, yankees);
citiField.playGame(9);

The demo for what I have is located here: http://jsfiddle.net/maniator/ueceeq7k/28/

const logger = ((logArea, logDelay = 0) => {
    const playArea = document.getElementById(logArea);
    return {
        delay: logDelay,
        log(...args) {
            let div = document.createElement('div');
       
      // Can see the result in the console
      console.log(...args);

            setTimeout(() => {
                // append to the top of the log
                playArea.insertBefore(div, playArea.firstChild);
                div.textContent = args.join(', ')
            }, this.delay);

            this.delay += logDelay;
        },
        logPad(...args) {
            this.log();
            this.log(...args);
        }
    };
})('playArea', 120);

const Team = (() => {
    const numberOfPlayers = 9;

    return class Team {
        constructor(name) {
            this.name = name;
            this.players = [];
            this.listeners = [];
            this.playerIndex = 0;
            this.score = 0;
            this.generatePlayers();
        }

        toString() {
            return this.name;
        }

        gainRun() {
            this.score++;
            logger.log(`${this} now have ${this.score} runs`);
        }

        generatePlayers() {
            for (let i = 0; i < numberOfPlayers; ++i) {
                this.players.push(new Player(`${this} Player ${i + 1}`, this));
            }

            this.pitcher = new Pitcher(`${this} Pitcher`, this);
        }

        nextPlayer() {
            this.playerIndex %= numberOfPlayers;

            let nextPlayer = this.players[this.playerIndex++];

            logger.log(`${nextPlayer} is up to bat`);

            return nextPlayer;
        }

        pitchTo(otherTeam) {
            let outs = 0;
            while (outs < 3) {
                let nextPlayer = otherTeam.nextPlayer();
                let strikes = 0;
                let balls = 0;

                while(strikes < 3 && balls < 4) {
                    let pitch = this.pitcher.pitch();
                    let hit = nextPlayer.acceptPitch(strikes, balls);

                    if (hit.out) {
                        outs++;

                        logger.log(`${nextPlayer} hit the ball!`);
                        logger.log(`${nextPlayer} hit a ${hit.name}`);
                        break;
                    }

                    if (hit.bases === 0) {
                        if (hit.strike) {
                            strikes++;
                            logger.log(`${nextPlayer} swung and missed`);
                        } else {
                            if (pitch.strike) {
                                strikes++;
                            } else {
                                balls++;
                            }
                            logger.log(`${nextPlayer} waited and got a ${pitch.name}`);
                        }
                    } else {
                        logger.log(`${nextPlayer} hit the ball!`);
                        this.trigger('Hit', nextPlayer, hit);
                        logger.log(`${nextPlayer} got a ${hit.name}`);
                        break;
                    }
                }

                if (strikes >= 3) {
                    outs++;
                    logger.log(`${nextPlayer} struck out`);
                } else if (balls >=4) {
                    logger.log(`${nextPlayer} walked`);
                    this.trigger('Hit', nextPlayer, {
                        bases: 1,
                    });
                }
            }
        }

        addListener(object) {
            if (!!object.trigger) {
                this.listeners.push(object);
            }
        }

        trigger() {
            this.listeners.forEach((listener) => listener.trigger(...arguments))
        }
    };
})();

class Player {
    constructor(name, team) {
        this.name = name;
        this.team = team;
    }

    toString() {
        return this.name;
    }

    acceptPitch(strikes = 0, balls = 0) {
        const random = Math.floor(Math.random() * 1000);
        const swingRate = 500 - (75 * strikes) + (30 * balls);

        if (random < swingRate) {
            return {
                name: 'swing and a miss',
                bases: 0,
                out: false,
                strike: true,
            };
        } else if (random < 880) { // wait for the pitch or hit into an out
            if (random > 830) {
                return {
                    name: 'fly out',
                    bases: 0,
                    out: true,
                };
            } else if (random > 810) {
                return {
                    name: 'ground out',
                    bases: 0,
                    out: true,
                };
            }

            return {
                name: 'wait',
                bases: 0,
                out: false,
            };
        } else if (random <= 1000) { // hit the ball
            if (random > 940 && random < 970) {
                return {
                    name: 'double',
                    bases: 2,
                    out: false,
                };
            }
            else if (random >= 970 && random < 995) {
                return {
                    name: 'triple',
                    bases: 3,
                    out: false,
                };
            }
            else if(random >= 995){
                return {
                    name: 'homerun',
                    bases: 4,
                    out: false,
                };
            } else {
                return {
                    name: 'single',
                    bases: 1,
                    out: false,
                };
            }
        }
    }
};

class Pitcher extends Player {
    static get pitchTypes() {
        // @todo math this SH*T up
        return [{
            name: 'strike',
            strike: true,
        },{
            name: 'ball',
            strike: false,
        },{
            name: 'strike',
            strike: true,
        },];
    }

    pitch() {
        const types = Pitcher.pitchTypes;
        const random = Math.floor(Math.random() * (types).length);
        logger.log(`${this} threw the ball`);
        return types[random];
    }
};

const Stadium = ((diamondArea) => {
    const diamondDiv = document.getElementById(diamondArea);
    let firstBase = false,
        secondBase = false,
        thirdBase = false,
        home = false;

    return class Stadium {
        constructor(a, b) {
            // @todo checks that a and b are team objects
            this.teams = [a, b];
        }

        firstBase(player) {
            if (firstBase && player) {
                logger.log(`${firstBase} ran to second`);
                this.secondBase(firstBase);
            }
            firstBase = player;
        }

        secondBase(player) {
            if (secondBase && player) {
                logger.log(`${secondBase} ran to third`);
                this.thirdBase(secondBase);
            }
            secondBase = player;
        }

        thirdBase(player) {
            if (thirdBase && player) {
                logger.log(`${thirdBase} ran home`);
                this.home(thirdBase);
            }
            thirdBase = player;
        }

        home(player) {
            player.team.gainRun();
        }

        single(player) {
            this.firstBase(player);
            logger.log(`${player} ran to first base`);
        }

        double(player) {
            this.single(player);
            this.secondBase(player);
            this.firstBase(false);
            logger.log(`${player} ran to second base`);
        }

        triple(player) {
            this.double(player);
            this.thirdBase(player);
            this.secondBase(false);
            logger.log(`${player} ran to third base`);
        }

        homerun(player) {
            this.triple(player);
            this.home(player);
            this.thirdBase(false);
            logger.log(`${player} ran to home base`);
        }

        get baseTypes() {
            return [this.homerun, this.single, this.double, this.triple];
        }

        clear() {
            firstBase = secondBase = thirdBase = false;

            return this;
        }

        playGame(innings) {
            let extraInnings = 0;
            let [teamA, teamB] = this.teams;
            logger.log(`${innings} inning game!`);
            this.listenToTeamActions();
            for (let i = 1; i <= innings; ++i) {
                logger.logPad(`Playing inning ${i} of ${innings}`);
                this.playInning(i);
            }

            while (teamA.score === teamB.score) {
                extraInnings++;
                logger.logPad(`EXTRA INNINGS!`);
                logger.logPad(`Score: ${teamA}: ${teamA.score} to ${teamB}: ${teamB.score}`);

                this.playInning(`EXTRA ${extraInnings}`);
            }

            logger.logPad(`GAME OVER${extraInnings ? ` WITH ${extraInnings} EXTRA INNINGS!` : '!'}`);
            logger.logPad(`Score: ${teamA}: ${teamA.score} to ${teamB}: ${teamB.score}`);
        }

        playInning(index) {
            let [teamA, teamB] = this.teams;

            logger.logPad(`${teamB} are up to bat in inning ${index}`);
            teamA.pitchTo(teamB);

            this.clear();

            logger.logPad(`${teamA} are up to bat in inning ${index}`);
            teamB.pitchTo(teamA);

            this.clear();
        }

        listenToTeamActions() {
            let [teamA, teamB] = this.teams;

            teamA.addListener(this);
            teamB.addListener(this);
        }

        trigger(event, ...args) {
            // @todo make first letter of event uppercase
            if (!!this[`on${event}`]) {
                this[`on${event}`](...args);
            }
        }

        onHit(player, type) {
            const baseTypes = this.baseTypes;
            const numberOfBases = type.bases % 4;

            baseTypes[numberOfBases].bind(this)(player);
        }
    };
})('diamond');

const mets = new Team('Mets');
const yankees = new Team('Yankees');
const citiField = new Stadium(mets, yankees);
console.log(mets, yankees);
citiField.playGame(9);
added 6 characters in body
Source Link
Naftali
  • 1.1k
  • 2
  • 13
  • 33
Loading
Rollback to Revision 1
Source Link
Naftali
  • 1.1k
  • 2
  • 13
  • 33
Loading
added 973 characters in body
Source Link
Naftali
  • 1.1k
  • 2
  • 13
  • 33
Loading
Source Link
Naftali
  • 1.1k
  • 2
  • 13
  • 33
Loading