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