James Woods wrote:
> Greetings all,
>
> The address of the page that I'm working on is
> http://staff.washington.edu/guru/cards.cgi
>
> The page seems like it should be pretty simple... but I'm a total newbie
to
> perl.
>
> When you check various boxes in the "Play" column and click "Update" the
> following should happen:
> 1) the checked cards should be removed from the "Draw Deck"
> 2) the checked cards should be added to "Played Cards"
>
> The cards are removed from the "Draw Deck" just fine, but the "Played
Cards"
> side is populated with the next card in the "Draw Deck" list (as opposed
to
> the exact card you checked).  It's easiest to just check the first card,
and
> pay attention to the second card.  The second card will show up in the
> "Played Cards" list, but the first card (the one you checked) gets removed
> from the "Draw Deck".
>
> I'm figuring that I'm just missing some @rray thing (being 0-based and
all),
> but I just can't see what I'm doing wrong.

The problem is that you are replacing your draw array with a new array from
which you've removed the played cards before you are getting the card names
that have been played, so the indexing changes. Your script has a few other
problems, some of which I've pointed out. See my notes in the code below.

> #!/usr/local/bin/perl
> #include <stdlib.h>

How did this get in here?

> use CGI qw(:standard);
> use strict;
>
> #This program needs several text files
> # 1) deck.txt => The whole deck
> # 2) draw.txt => The draw deck
> # 3) played.txt => all cards that have been played
> #
> #Each time the page is "updated" (by clicking on "update" in the form:
> #     1) the draw.txt file should be created anew with all the played
> #        (checked) cards removed
> #     2) the played.txt file should be created anew with all the played
> #        (checked) cards appended

   You do realize that if more than one person is using your script at once
they're going to clobber each other's state, right? Even if you're just
doing it temporarily this way it's a problem once you give out the url for
people to debug. If five people from the list go look at it at the same time
it's going to be confusing.

> print "Content-type: text/html\n\n";
>
> print qq{
> <p><a href="cards.cgi">Start Over</a></p>
> };
>
> my @Deck; # The whole deck, orderd
> my @Draw; # The current, shuffled deck
> my @playedCardsCheckbox = param("playedCardsCheckbox") || "";
> my @playedCards;
> my $iterate;
> my $random;
> my $control;
> my $counter = 0;
> my $valueName;
>
> # if the update button has NOT been pressed.
> # e.g. when the page is just run for the first time.
>
> if (param("update") eq "no" || param("update") eq undef){
>
> unlink ("played.txt");
>
> open (DECK,"deck.txt");
> @Deck = <DECK>;
> close DECK;
>
> @Draw = @Deck;
>
> &Randomize (\@Draw);
>
> open (DRAW,">draw.txt") || &CgiDie ("Cannot open $!");
> foreach my $item (@Draw){
> print DRAW $item;
> }
> close DRAW;
>
> # The else happens when the update button has been pressed.
>
> }else{
>
> # The DRAW file is used to keep track of the 'shuffle order'
>
> open (DRAW,"draw.txt");
> @Draw = <DRAW>;
> close DRAW;
>
> if (playedCardsCheckbox){
>
>    #print param("playedCardsCheckbox");
>      foreach my $item (@Draw){
>      @Draw[param("playedCardsCheckbox")] = ("");
>      }
> }
>

>From your played card code it seems like you know that
param("playedCardsCheckbox") returns a list (the player can play more than
one card in a turn). The assignment above doesn't need to be in a loop- it
assigns to each index in the returned list in one fell swoop (note that this
only works because you're setting these elements to ""- if you were trying
to set them to "played" it would fail if there were more than one). The
foreach just repeats that action over and over again. You could just write:

@Draw[param("playedCardsCheckbox")] = "";

But I think it would be clearer to write:

foreach my $item (param("playedCardsCheckbox")){
   @Draw[$item]= "";
}

> open (DRAW,">draw.txt");
> foreach my $item (@Draw){
>    if ($item ne ""){
>       print DRAW $item;
>       }
> }
> close DRAW;
>
> open (DRAW,"draw.txt");
> @Draw = <DRAW>;
> close DRAW;

This is where your problem is happening. You just set @Draw to a new shorter
array.

> # The PLAYED file is used to keep track of what cards have been
> #   played.  This file populates the playedCards select box.
>
> open (PLAYED,"played.txt");
> @playedCards = <PLAYED>;
> close PLAYED;
>
> if (playedCardsCheckbox){
>
>      print param("playedCardsCheckbox");
>      foreach my $item (param("playedCardsCheckbox")){
>      print @playedCards[$item],"<br>";
>      push(@playedCards, "$Draw[$item]");
>      }
> }

Now you retrieve the values. But the indexing of @Draw has changed.

> open (PLAYED,">>played.txt");
> foreach my $item (@playedCards){
> print PLAYED "$item";
> }
> close PLAYED;

   This is wrong. Try this- Start a game, play one card, and then hit the
submit button a few times. You'll see that the list of played cards grows,
even though you're not playing any cards. This is because you keep appending
the played card file onto itself. You need to overwrite the played card
values, or just append the newly played cards.

<snip rest of message>

   The main problem here is that the control flow is a bit confusing,
particularly with all that writing and reading of files, sometimes
repeatedly. You might want to rethink it some.

Tagore Smith


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to