[Neworleans-pm] Fwd: Perl 'Expert' Quiz of the Week #23

E. Strade, B.D. estrabd at yahoo.com
Thu Sep 9 07:28:41 CDT 2004




=====
http://www.brettsbsd.net/~estrabd

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

----- Original message -----
From: "Rick Measham" <rickm at printaform.com.au>
To: perl-qotw at plover.com
Date: Wed, 08 Sep 2004 22:23:24 -0400
Subject: Perl 'Expert' Quiz of the Week #23


IMPORTANT: Please do not post solutions, hints, or other spoilers
        until at least 60 hours after the date of this message.
        Thanks.

IMPORTANTE: Por favor, no enviéis soluciones, pistas, o cualquier otra
        cosa que pueda echar a perder la resolución del problema hasta
        que hayan pasado por lo menos 60 horas desde el envío de este
        mensaje. Gracias.

WICHTIG: Bitte schicken Sie keine Lösungen, Tipps oder Hinweise für
        diese Aufgabe vor Ablauf von 60 Stunden nach dem Datum dieser
        Mail. Danke.

VNIMANIE: Pozhalujsta ne shlite reshenija, nameki na reshenija, i
        voobshe lyubye podskazki v techenie po krajnej mere 60 chasov
        ot daty etogo soobshenija.  Spasibo.

Qing3 Zhu4Yi4: Qing3 Ning2 Deng3Dao4 Jie1Dao4 Ben3 Xin4Xi2 Zhi1Hou4 60
        Xiao3Shi2, Zai4 Fa1Biao3 Jie3Da2, Ti2Shi4, Huo4 Qi2Ta1 Hui4
        Xie4Lou4 Da2An4 De5 Jian4Yi4.  Xie4Xie4.

----------------------------------------------------------------


The aim this fortnight is to write a tetris game -- a problem that  
should be both fun to write and fun to use.

The problem is split into three milestones. Each milestone adds  
functionality to the game to the point where we can play each other  
across the internet.

#----------------------------------------------------------------------- 
PRIMARY MILESTONE:
Write a single-user tetris game.
#----------------------------------------------------------------------- 

Tetris is a simple graphical game that can be implemented on almost any  
interface, from a text display to a full-blown three dimensional  
graphical interface.

A game grid is 10 spaces wide and 20 spaces high. Gravity pulls random  
blocks toward the bottom of the grid until the bottom surface of any  
portion of the block touches another block or the bottom of the game  
grid.

Gravity pulls blocks downward at a rate starting at one space per
second (we'll call that the 'gravity-period'.

The player can alter the way the block drops in four ways:
- Move left: The player can move the dropping block one space to the
left
- Move right: The player can move the dropping block one space to the
right
- Move down: The player can move the dropping block one space down
- Rotate: The player can rotate the block clockwise 90 degrees
   (optionally you may also allow an anti-clockwise rotate)

The player is not limited to the number of actions they take in each  
gravity-period by anything other than the speed of the interface.

There are seven block shapes that fall:

    ##   @@  %%   ***  &&&  ++++  $$$
    ##  @@    %%  *      &         $

Once the block reaches ground-level another gravity-period elapses
before it is cemented in place. This allows the player to move the
block left or right at the last moment, as shown below. The '#' block
is moved:

        4|&&        |  |&&        |
        3|& ##      |  |&##       |
        2|& ##      |  |&##       |
        1+----------+  +----------+
          ABCDEFGHIJ    ABCDEFGHIJ

Each time a complete horizonal row in the grid is completed, its
contents disappear and the contents of the rows above it drop down to
fill the vacated spaces. The example below shows a block landing and
completing row 2.  One gravity-period later, row 2 has disappeared,
and rows 3 and 4 have dropped down one space:

        4|&&        |  |          |
        3|&##    &  |  |&&        |
        2|&##++++&&&|  |&##    &  |
        1|++++  ++++|  |++++  ++++|
         +----------+  +----------+
          ABCDEFGHIJ    ABCDEFGHIJ

After each 10 complete rows are deleted in this way, the difficulty
level increases.  Difficulty level $n's gravity-period is (1 /
1.3**($n-1)) seconds. Each completed row scores the user $c * $n where
$c is the number of blocks removed at a single time (in the default
grid, that would be 10 times the number of rows removed as there are
10 columns).

The aim of the game is to successfully place as many blocks as
possible before one of the blocks touches the top of the grid. Here's
a game that's finished -- you'll note that the top '%' block touches
the top of the grid:

          +----------+
        20|     %    |
        19|    %%    |
        18|    %     |
        17|    +     |
        16|    +     |
        15|    +     |
        14|    +     |
        13|   &&     |
        12|   &      |
        11|   &      |
        10|   +      |
         9|   +      |
         8|   +      |
         7|   +      |
         6|   &      |
         5|   &      |
         4|  &&      |
         3| ##       |
         2| ##       |
         1|++++      |
          +----------+
           ABCDEFGHIJ

The player scores one point for each unit of the perimeter of the
dropped shape that touches a previously dropped block or the edge of
the grid. In the example game below, the '&' block was dropped onto a
blank grid and scored 5 points.  Then the '$' block was then dropped and
scored 3 points: two points for its two contacts with the '&' block
and one point for its contact with the bottom of the grid:

          4|   $      |
          3|& $$      |
          2|&&&$      |
          1+----------+
            ABCDEFGHIJ

You may choose to use any reasonable interface that you want.  It will
be interesting to see solutions in ncurses, tk or anything else. (Note
that I'll be testing it on MacOS-X and RedHat linux)

The interface should show the entire game grid and should also show  
which block will drop next.

Any of the above options can be changed except the block shapes. You
can allow users to change the gravity-period or the grid size.
However, the defaults are as above.

The default action keys should be:

        Z - left
        X - right
        / - down
        ' - rotate

If you have extra time, you may want to implement some of the
following extensions to the project:

#----------------------------------------------------------------------- 
EXTENSION 1
Allow two-user game play
#----------------------------------------------------------------------- 

In this version of the quiz you will allow a second user to select
which block will drop next. This selection will be from three randomly
selected blocks and should be selected using the 1, 2 and 3
keys. These three pieces should be displayed in the interface.

Should the second player not select a block before it is needed, one
should be selected at random from the three choices.

#----------------------------------------------------------------------- 
EXTENSION 2
Write a split engine/interface tetris game
#----------------------------------------------------------------------- 

In this version of the quiz the interface should be split from the
engine. Two interfaces should be able to link to a given engine, one
for each player.  (Optionally, extra interfaces may connect but only
to view the game, not play)

The interface should connect to the engine via a network socket.

The command set should be standardised so your interface can plug into
my engine or vice versa.

The client will send the server commands on each keypress:

        LEFT
        RIGHT
        DOWN
        ROTATE

A second client (for player 2) can send:

        ONE
        TWO
        THREE

to indicate the selected piece. In the split game (where the two
players are using different clients) there is no requirement for
player 1 to see the three options given to player 2 until one becomes
the 'next block'.

The server will send the client diffs of the game board. The following  
change would be transmitted as:

        D03 D02 B03#B02#

  4|&&        |  |&&        |
  3|& ##      |  |&##       |
  2|& ##      |  |&##       |
  1+----------+  +----------+
    ABCDEFGHIJ    ABCDEFGHIJ

The format of the message string is:

        ($col,$row,$piece) =~ /([A-J])(\d\d)([\Q#@%*&+$\E])/

#----------------------------------------------------------------------- 
REFERENCES
#----------------------------------------------------------------------- 

Screenshot of original tetris:

        http://www.mobygames.com/images/shots/original/1018986079-00.gif

History of tetris (from Atari's point of view -- there was a court
battle):

        http://www.atarihq.com/tsr/special/tetrishist.html

Javascript Implementation of the game if you've never played it:

        http://www.js-games.de/eng/games/tetris




More information about the NewOrleans-pm mailing list