157288Sbostic /*- 2*60854Sbostic * Copyright (c) 1992, 1993 3*60854Sbostic * The Regents of the University of California. All rights reserved. 457288Sbostic * 557288Sbostic * This code is derived from software contributed to Berkeley by 657288Sbostic * Chris Torek and Darren F. Provine. 757288Sbostic * 857288Sbostic * %sccs.include.redist.c% 957288Sbostic * 10*60854Sbostic * @(#)tetris.h 8.1 (Berkeley) 05/31/93 1157288Sbostic */ 1257288Sbostic 1357277Sbostic /* 1457277Sbostic * Definitions for Tetris. 1557277Sbostic */ 1657277Sbostic 1757277Sbostic /* 1857277Sbostic * The display (`board') is composed of 23 rows of 12 columns of characters 1957277Sbostic * (numbered 0..22 and 0..11), stored in a single array for convenience. 2057277Sbostic * Columns 1 to 10 of rows 1 to 20 are the actual playing area, where 2157277Sbostic * shapes appear. Columns 0 and 11 are always occupied, as are all 2257277Sbostic * columns of rows 21 and 22. Rows 0 and 22 exist as boundary areas 2357277Sbostic * so that regions `outside' the visible area can be examined without 2457277Sbostic * worrying about addressing problems. 2557277Sbostic */ 2657277Sbostic 2757277Sbostic /* the board */ 2857277Sbostic #define B_COLS 12 2957277Sbostic #define B_ROWS 23 3057277Sbostic #define B_SIZE (B_ROWS * B_COLS) 3157277Sbostic 3257277Sbostic typedef unsigned char cell; 3357277Sbostic cell board[B_SIZE]; /* 1 => occupied, 0 => empty */ 3457277Sbostic 3557277Sbostic /* the displayed area (rows) */ 3657277Sbostic #define D_FIRST 1 3757277Sbostic #define D_LAST 22 3857277Sbostic 3957277Sbostic /* the active area (rows) */ 4057277Sbostic #define A_FIRST 1 4157277Sbostic #define A_LAST 21 4257277Sbostic 4357277Sbostic /* 4457277Sbostic * Minimum display size. 4557277Sbostic */ 4657277Sbostic #define MINROWS 23 4757277Sbostic #define MINCOLS 40 4857277Sbostic 4957277Sbostic int Rows, Cols; /* current screen size */ 5057277Sbostic 5157277Sbostic /* 5257277Sbostic * Translations from board coordinates to display coordinates. 5357277Sbostic * As with board coordinates, display coordiates are zero origin. 5457277Sbostic */ 5557277Sbostic #define RTOD(x) ((x) - 1) 5657277Sbostic #define CTOD(x) ((x) * 2 + (((Cols - 2 * B_COLS) >> 1) - 1)) 5757277Sbostic 5857277Sbostic /* 5957277Sbostic * A `shape' is the fundamental thing that makes up the game. There 6057277Sbostic * are 7 basic shapes, each consisting of four `blots': 6157277Sbostic * 6257277Sbostic * X.X X.X X.X 6357277Sbostic * X.X X.X X.X.X X.X X.X.X X.X.X X.X.X.X 6457277Sbostic * X X X 6557277Sbostic * 6657277Sbostic * 0 1 2 3 4 5 6 6757277Sbostic * 6857277Sbostic * Except for 3 and 6, the center of each shape is one of the blots. 6957277Sbostic * This blot is designated (0,0). The other three blots can then be 7057277Sbostic * described as offsets from the center. Shape 3 is the same under 7157277Sbostic * rotation, so its center is effectively irrelevant; it has been chosen 7257277Sbostic * so that it `sticks out' upward and leftward. Except for shape 6, 7357277Sbostic * all the blots are contained in a box going from (-1,-1) to (+1,+1); 7457277Sbostic * shape 6's center `wobbles' as it rotates, so that while it `sticks out' 7557277Sbostic * rightward, its rotation---a vertical line---`sticks out' downward. 7657277Sbostic * The containment box has to include the offset (2,0), making the overall 7757277Sbostic * containment box range from offset (-1,-1) to (+2,+1). (This is why 7857277Sbostic * there is only one row above, but two rows below, the display area.) 7957277Sbostic * 8057277Sbostic * The game works by choosing one of these shapes at random and putting 8157277Sbostic * its center at the middle of the first display row (row 1, column 5). 8257277Sbostic * The shape is moved steadily downward until it collides with something: 8357277Sbostic * either another shape, or the bottom of the board. When the shape can 8457277Sbostic * no longer be moved downwards, it is merged into the current board. 8557277Sbostic * At this time, any completely filled rows are elided, and blots above 8657277Sbostic * these rows move down to make more room. A new random shape is again 8757277Sbostic * introduced at the top of the board, and the whole process repeats. 8857277Sbostic * The game ends when the new shape will not fit at (1,5). 8957277Sbostic * 9057277Sbostic * While the shapes are falling, the user can rotate them counterclockwise 9157277Sbostic * 90 degrees (in addition to moving them left or right), provided that the 9257277Sbostic * rotation puts the blots in empty spaces. The table of shapes is set up 9357277Sbostic * so that each shape contains the index of the new shape obtained by 9457277Sbostic * rotating the current shape. Due to symmetry, each shape has exactly 9557277Sbostic * 1, 2, or 4 rotations total; the first 7 entries in the table represent 9657277Sbostic * the primary shapes, and the remaining 12 represent their various 9757277Sbostic * rotated forms. 9857277Sbostic */ 9957277Sbostic struct shape { 10057277Sbostic int rot; /* index of rotated version of this shape */ 10157277Sbostic int off[3]; /* offsets to other blots if center is at (0,0) */ 10257277Sbostic }; 10357277Sbostic 10457277Sbostic extern struct shape shapes[]; 10557277Sbostic #define randshape() (&shapes[random() % 7]) 10657277Sbostic 10757277Sbostic /* 10857277Sbostic * Shapes fall at a rate faster than once per second. 10957277Sbostic * 11057277Sbostic * The initial rate is determined by dividing 1 million microseconds 11157277Sbostic * by the game `level'. (This is at most 1 million, or one second.) 11257277Sbostic * Each time the fall-rate is used, it is decreased a little bit, 11357277Sbostic * depending on its current value, via the `faster' macro below. 11457277Sbostic * The value eventually reaches a limit, and things stop going faster, 11557277Sbostic * but by then the game is utterly impossible. 11657277Sbostic */ 11757277Sbostic long fallrate; /* less than 1 million; smaller => faster */ 11857277Sbostic #define faster() (fallrate -= fallrate / 3000) 11957277Sbostic 12057277Sbostic /* 12157277Sbostic * Game level must be between 1 and 9. This controls the initial fall rate 12257277Sbostic * and affects scoring. 12357277Sbostic */ 12457277Sbostic #define MINLEVEL 1 12557277Sbostic #define MAXLEVEL 9 12657277Sbostic 12757277Sbostic /* 12857277Sbostic * Scoring is as follows: 12957277Sbostic * 13057277Sbostic * When the shape comes to rest, and is integrated into the board, 13157277Sbostic * we score one point. If the shape is high up (at a low-numbered row), 13257277Sbostic * and the user hits the space bar, the shape plummets all the way down, 13357277Sbostic * and we score a point for each row it falls (plus one more as soon as 13457277Sbostic * we find that it is at rest and integrate it---until then, it can 13557277Sbostic * still be moved or rotated). 13657277Sbostic */ 13757277Sbostic int score; /* the obvious thing */ 13857277Sbostic 13957277Sbostic char key_msg[100]; 14057277Sbostic 14157277Sbostic int fits_in __P((struct shape *, int)); 14257277Sbostic void place __P((struct shape *, int, int)); 14357277Sbostic void stop __P((char *)); 144