Voting

Category

real language

Bookmarking

Del.icio.us Digg Diigo DZone Earthlink Google Kick.ie
Windows Live LookLater Ma.gnolia Reddit Rojo StumbleUpon Technorati

Language C#

Date:04/20/05
Author:Paul M. Parks
URL:n/a
Comments:9
Info:n/a
Score: (2.97 in 148 votes)
/// Implementation of Ninety-Nine Bottles of Beer Song in C#.
/// What's neat is that .NET makes the Binge class a 
/// full-fledged component that may be called from any other 
/// .NET component.
///
/// Paul M. Parks
/// http://www.parkscomputing.com/
/// February 8, 2002
/// 

using System;

namespace NinetyNineBottles
{
    /// <summary>
    /// References the method of output.
    /// </summary>
    public delegate void Writer(string format, params object[] arg);

    /// <summary>
    /// References the corrective action to take when we run out.
    /// </summary>
    public delegate int MakeRun();

    /// <summary>
    /// The act of consuming all those beverages.
    /// </summary>
    public class Binge
    {
        /// <summary>
        /// What we'll be drinking.
        /// </summary>
        private string beverage;

        /// <summary>
        /// The starting count.
        /// </summary>
        private int count = 0;

        /// <summary>
        /// The manner in which the lyrics are output.
        /// </summary>
        private Writer Sing;

        /// <summary>
        /// What to do when it's all gone.
        /// </summary>
        private MakeRun RiskDUI;

        public event MakeRun OutOfBottles;


        /// <summary>
        /// Initializes the binge.
        /// </summary>
        /// <param name="count">How many we're consuming.</param>
        /// <param name="disasterWaitingToHappen">
        /// Our instructions, should we succeed.
        /// </param>
        /// <param name="writer">How our drinking song will be heard.</param>
        /// <param name="beverage">What to drink during this binge.</param>
        public Binge(string beverage, int count, Writer writer)
        {
            this.beverage = beverage;
            this.count = count;
            this.Sing = writer;
        }

        /// <summary>
        /// Let's get started.
        /// </summary>
        public void Start()
        {
            while (count > 0)
            {
                Sing(
                    @"
{0} bottle{1} of {2} on the wall,
{0} bottle{1} of {2}.
Take one down, pass it around,", 
                    count, (count == 1) ? "" : "s", beverage);

                count--;

                if (count > 0)
                {
                    Sing("{0} bottle{1} of {2} on the wall.",
                        count, (count == 1) ? "" : "s", beverage);
                }
                else
                {
                    Sing("No more bottles of {0} on the wall.", beverage, null);
                }

            }

            Sing(
                @"
No more bottles of {0} on the wall,
No more bottles of {0}.", beverage, null);

            if (this.OutOfBottles != null)
            {
                count = this.OutOfBottles();
                Sing("{0} bottles of {1} on the wall.", count, beverage);
            }
            else
            {
                Sing("First we weep, then we sleep.");
                Sing("No more bottles of {0} on the wall.", beverage, null);
            }
        }
    }

    /// <summary>
    /// The song remains the same.
    /// </summary>
    class SingTheSong
    {
        /// <summary>
        /// Any other number would be strange.
        /// </summary>
        const int bottleCount = 99;

        /// <summary>
        /// The entry point. Sets the parameters of the Binge and starts it.
        /// </summary>
        /// <param name="args">unused</param>
        static void Main(string[] args)
        {
            Binge binge = 
               new Binge("beer", bottleCount, new Writer(Console.WriteLine));
            binge.OutOfBottles += new MakeRun(SevenEleven);
            binge.Start();
        }

        /// <summary>
        /// There's bound to be one nearby.
        /// </summary>
        /// <returns>Whatever would fit in the trunk.</returns>
        static int SevenEleven()
        {
            Console.WriteLine("Go to the store, get some more...");
            return bottleCount;
        }
    }
}

Download Source | Write Comment

Alternative Versions

VersionAuthorDateCommentsRate
Concise, using C# 3.5 featuresJeff Dietrich10/26/0714
C# Gratuitously FunctionalPaul Stancer04/14/091
corporate styleveteran corporate coder08/16/090
4Mark Hurley05/31/050
Uses LinqSudipta11/19/100
Shows new features of C# 2.0.Bradley Tetzlaff11/24/050
v3.0 Easy Functional RecursiveYelinna Pulliti Carrasco08/04/090

Comments

>>  huh? said on 05/15/05 04:03:38

huh? I'm still trying to find Main.

>>  Stefan Scheler said on 05/18/05 15:19:13

Stefan Scheler Main is imho in class SingTheSong.

I applied a patch from Tamara Roberson. She said the code had some other problem as well. Unfortunately, I can't test it since I don't have C# available atm. Can anyone give feedback, if the code is correct now?

>>  RacerX said on 05/20/05 03:09:29

RacerX Totally over-cooked, but I give 4 stars for creativity.

>>  Paul M. Parks said on 06/22/05 05:26:47

Paul M. Parks Yeah, I'll admit it's overcooked. I trying to show off some C#/.NET features when I wrote it. I have a webpage that actually uses the Binge class above to generate the lyrics dynamically. It's at http://www.parkscomputing.com/dotnet/99bottles.aspx

And yes, Main is in SingTheSong.

>>  mala said on 08/29/05 17:05:50

mala java, c#... i guess we can't really get any more verbose and stupid...

still, since it's just a showoff, i'll give you the benefit of doubt... ;)

>>  S Martin said on 07/09/06 07:12:29

S Martin One more reason to be switching to Ruby.

>>  Andre said on 04/16/07 11:22:35

Andre Now don't form an opinion of C# just because this guy wrote a simple program in such a "messy" way. He should have at least taken out the comments for clarity. I wrote this program in a much simpler way - a lot like Bradley Tetzlaff's

>>  procedure said on 11/06/08 00:15:40

procedure This is true code. ;)

>>  csharptutorial said on 01/16/09 21:58:41

csharptutorial sorry dude, the Start() method is way too long and hideous to look at. I liked the inheritance and polymorphism based sample I sent in which also used interfaces and the factory pattern. I wish they would post it.

Download Source | Write Comment

Add Comment

Please provide a value for the fields Name, Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.

Please don't post large portions of code here! Use the form to submit new examples or updates instead!

Name:

eMail:

URL:

Security Code:
  
Comment: