Sample Source Code
Vineyard Challenge!: results.pl

About the Code

"Vineyard Challenge!" is an interactive web game. You start out with some money, and try to buy vineyards, grow grapes, and sell them. The object of the game, of course, is to try to make the most money. Random events (weather, bugs, and market prices) greatly effect the outcome of the game, but there is still some strategy involved. The concept of the game is loosely based on the ancient Applesoft Basic game called "Lemonade Stand".

This game was written for the McCarty Corportation. It can be played live at http://www.mccarty.com/vineyard/.

This module provides the code for showing the user the results of the last grape growing season, and a nice 'game over' page congratulating the user once they've finished the game.

The Code

# Part of the 'Vineyard Challenge' game.
# Copyright (c) 1995 by Triangle Street Diversions.  All rights reserved.


# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# SUBROUTINE: VIEW MARKET RESULTS
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------


sub ViewMarketResults {
    local( $i, $j, $this, $val );
    local( $bugs, $weather );
    local( @ate, @destroyed );
    local( $profit );
    local( @ratings );

    # display the year range for this turn.
    &Header;
    &SubHeader( &Year( 'range' ), $subhead_market_results );

    # determine the bugs and weather.
    $bugs      = $in{ 'market_bugs' };
    $weather   = $in{ 'market_weather' };
    @ate       = &MarketBugsAte;
    @destroyed = &MarketWeatherDestroyed;

    # display the weather results.
    print "<H3>Weather report:</H3>\n";
    print "<CENTER><P ALIGN=CENTER>\n";
    print "The weather was ";
    print $weather_description[ $weather ];
    print ".<BR>";
    for ( $i = 0; $i < $weather; $i++ ) {
        &Image( $url_icon_storm, "ALIGN=CENTER" );
        print "\n";
    }
    print "</P></CENTER>\n";

    # display the bug results.
    print "<H3>Bug report:</H3>\n";
    print "<CENTER><P ALIGN=CENTER>\n";
    print "Bug infestations were ";
    print $bug_description[ $bugs ];
    print ".<BR>";
    for ( $i = 0; $i < $bugs; $i++ ) {
        &Image( $url_icon_bug, "ALIGN=CENTER" );
        print "\n";
    }
    print "</P></CENTER>\n";

    # display the market results.
    @ratings = &MarketRatings;
    print "<H3>Market results:</H3>\n";
    for ( $i = 0; $i <= $#grape_name; $i++ ) {
        print "<P>\n";
        &Image( $url_icon_grape, 'ALIGN=CENTER' );
        print "<FONT SIZE =+1>\n";
        print &cap( $grape_name[ $i ] );
        print "</FONT>\n";
        print " grapes ";
        print $market_description[ $ratings[ $i ] ];
        print ".<BR>\n";
        print "<CENTER>\n";
        for ( $j = 0; $j < $ratings[ $i ]; $j++ ) {
             &Image( $url_icon_rating );
        }
        print "</CENTER>\n";
        print "</P>\n";
    }

    # provide a button to advance.
    $out{ 'current_step' } = 'view your results';
    &FormOpen;
    print "<CENTER><P ALIGN=CENTER>\n";
    print '<INPUT TYPE="submit" NAME="foo" VALUE="';
    print $button_your_results;
    print '">';
    print "</P></CENTER>\n";
    print "\n";
    &FormClose;

    &Footer;
}


# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# SUBROUTINE: VIEW YOUR RESULTS
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------


sub ViewYourResults {
    local( $i, $this, $grape, $root, $respect );
    local( $profit );
    local( @yield, @value );
    local( @ate, @destroyed );

    # display the year range for this turn.
    &Header;
    &SubHeader( &Year( 'range' ), $subhead_your_results );

    # determine the bugs and weather.
    $bugs      = $in{ 'market_bugs' };
    $weather   = $in{ 'market_weather' };
    @ate       = &MarketBugsAte;
    @destroyed = &MarketWeatherDestroyed;

    # determine the harvest and gold yields.
    @ratings = &MarketRatings;
    @yield   = &MarketCropsYielded;
    @gold    = &MarketGoldYielded;

    # if anything was destroyed, display that.
    if ( join( ' ', @destroyed ) =~ /[1-9]/ ) {
        print "<P>\n";
        for ( $i = 0; $i < $num_vineyards; $i++ ) {
            $this = $destroyed[ $i ];
            next if ( $this == 0 );
            ( $grape, $root ) = &Vineyard( $i );
            &Image( $url_icon_storm, "ALIGN=CENTER" );
            print "Storms destroyed <STRONG>$this</STRONG> unit";
            &plural( $this, "s");
            print " of $grape_name[ $grape ] grapes from your ";
            print &nth( $i + 1 );
            print " vineyard!\n";
            print "<BR>\n";
        }
        print "</P><HR>\n";
    }

    # if anything was eaten, display that.
    if ( join( ' ', @ate ) =~ /[1-9]/ ) {
        print "<P>\n";
        for ( $i = 0; $i < $num_vineyards; $i++ ) {
            $this = $ate[ $i ];
            next if ( $this == 0 );
            ( $grape, $root ) = &Vineyard( $i );
            &Image( $url_icon_bug, "ALIGN=CENTER" );
            print "Bugs ate <STRONG>$this</STRONG> unit";
            &plural( $this, "s");
            print " of $grape_name[ $grape ] grapes from your ";
            print &nth( $i + 1 );
            print " vineyard!\n";
            print "<BR>\n";
        }
        print "</P><HR>\n";
    }

    # display player's results.
    print "<P>\n";
    $profit = 0;
    for ( $i = 0; $i < $num_vineyards; $i++ ) {

        ( $grape, $root, $respect ) = &Vineyard( $i );

        # add on the profit from this vineyard.
        $profit += $gold[ $i ];

        # if this type of grape was well liked, increase respect.
        if ( $ratings[ $grape ] >= $rating_for_respect_increase ) {
            $respect++;
            $out{ 'vineyard_' . $vine_name[ $i ] } = "$grape $root $respect";
        }

        &Image( $url_icon_vineyard, 'ALIGN=CENTER' );
        print "Your ";
        print &nth( $i + 1 );
        print " vineyard produced \n";
        &Image( $url_icon_productivity, 'ALIGN=CENTER' );
        print " $yield[ $i ] unit";
        &plural( $yield[ $i ], "s");
        print " of $grape_name[ $grape ] grapes.<BR>\n";
        print "This crop sold for ";
        &Image( $url_icon_gold, 'ALIGN=CENTER' );
        &DisplayGoldText( $gold[ $i ] );
        print ".\n";
        print "<BR>\n";
    }
    print "</P>\n";

    # give the player their gold.
    $gold += $profit;
    $out{ 'gold' } = $gold;

    # tell the player about their gold.
    print "<HR>\n";
    print "<CENTER><P ALIGN=CENTER>\n";
    print "You raked in ";
    &Image( $url_icon_gold, 'ALIGN=CENTER' );
    &DisplayGoldText( $profit );
    print "...\n";
    print "</P><P ALIGN=CENTER>\n";
    print "That gives you a total of ";
    &Image( $url_icon_gold, 'ALIGN=CENTER' );
    &DisplayGoldText( $gold );
    print "!\n";
    print "</P></CENTER>\n";

    # increase the turn by one.
    $turn_number++;
    $out{ 'turn_number' } = $turn_number;

    # will the game end, or keep going?
    if ( $turn_number <= $max_turns ) {
        $out{ 'current_step' } = 'new turn';
    } else {
        $out{ 'current_step' } = 'game over';
    }

    # provide a button to advance.
    &FormOpen;
    print "<CENTER><P ALIGN=CENTER>\n";
    print '<INPUT TYPE="submit" NAME="foo" VALUE="';
    if ( $turn_number <= $max_turns ) {
        print $button_next_turn;
    } else {
        print $button_game_over;
    }
    print '">';
    print "\n";
    print "</P></CENTER>\n";
    &FormClose;

    &Footer;
}


# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# SUBROUTINE: GAME OVER
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------


sub GameOver {
    local( $subhead, $i, $split );
    local( $rank, $ranking, $years );

    $turn_number--;
    $years = &Year( 'end' );
    $years =~ s/Year //;

    &Header;
    &SubHeader( &Year( 'end' ), $subhead_game_over );

    ( $rank, $ranking ) = &Ranking( $gold, $num_vineyards );

    print "<CENTER><P ALIGN=CENTER><FONT SIZE=+1>\n";
    print "After $years years you retire, happy and content.\n";
    print "</FONT></P></CENTER>\n";

    # how much gold we had.
    &DisplayGold;

    # display the vineyards we own.
    for ( $i = 0; $i < $num_vineyards; $i++ ) {
        ( $grape, $root, $respect ) = &Vineyard( $i );
        &Image( $url_icon_new_vineyard[ $grape ], "ALIGN=CENTER" );
        print "\n";
        print "A $respect_description[ $respect ] ";
        print "$grape_name[ $grape ] vineyard with ";
        print "$root_name[ $root ]";
        print " root stock.\n";
        print "<BR>\n";
        print "<BR>\n";
    }
    print "<HR>\n";

    print "<P>\n";
    print "This gives you a ranking of: ";
    print "<STRONG><FONT SIZE=+1>\n";
    print $ranking;
    print "</FONT></STRONG>.\n";
    print "</P>\n";

    print "<CENTER><P ALIGN=CENTER>\n";
    $split = ( $rank < 9 ) ? -1 : int( ( $rank + 1 ) / 2 );
    for ( $i = 0; $i < $rank; $i++ ) {
         &Image( $url_icon_rating );
         print "<BR>\n" if ( $i == $split );
    }
    print "</P></CENTER>\n";
    print "<HR>\n";

    # provide a button to play again.
    reset %out;
    undef %out;
    $out{ 'start' } = 'yes';
    &FormOpen;
    print "<CENTER><P ALIGN=CENTER>\n";
    print '<INPUT TYPE="submit" NAME="foo" VALUE="';
    print $button_play_again;
    print '">';
    print "\n";
    print "</P></CENTER>\n";
    &FormClose;

    &ButtonBar;

    &Footer;
}


# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# SUPPORT FUNCTION: RANKING
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------

sub Ranking {
    local( $gold, $vineyards ) = @_;
    local( $i, $vine, $root, $respect );
    local( $assets, $rank );

    # count up the assets.
    # gold counts for its value.
    # vineyards count for half what they cost.
    $assets = $gold;
    for ( $i = 0; $i <= $num_vineyards; $i++ ) {
        ( $vine, $root, $respect ) = &Vineyard( $i );
        $assets += int( ( $vineyard_base_cost + $root_cost[ $root ] ) / 2 );
        $assets += 4 * $respect;
    }

    $rank = $assets / 20;

    if ( $rank < 0 ) { $rank = 0 };
    if ( $rank > $#rankings - 1 ) { $rank = $#rankings - 1 };

    ( $rank, $rankings[ $rank ] );
}

# ----------------------------------------------------------------------
# ----------------------------------------------------------------------

# return 'true' so the 'require' command doesn't fail!!

1;