All pastes #246643 Raw Edit

Clooth

public c v1 · immutable
#246643 ·published 2006-11-12 13:43 UTC
rendered paste body
/* TETRIS -- C** @author Clooth <CloothMail@Gmail.com>*/#include <conio.h>#include <stdio.h>#include <stdlib.h>/* MAIN GAME VARIABLES */#define SCREEN_WIDTH 10#define SCREEN_HEIGHT 20#define SCREEN_POSITION 20#define TYPES 19#define SIZE 4#define STARTSPEED 2000#define BLOCK_CHARACTER '[]'#define EMPTY_CHARACTER '  '#define BORDER '+'/* CONTROLS */#define LEFT 'z'#define RIGHT 'c'#define ROTATE 'm'#define END 'e'enum type{     square, horizontal_long, vertical_long,      stair1, stair2, stair3, stair4,     T_up, T_right, T_down, T_left,      L1_up, L1_right, L1_down, L1_left,      L2_up, L2_right, L2_down, L2_left};type modification[TYPES]={     square, horizontal_long, vertical_long,      stair1, stair2, stair3, stair4,     T_up, T_right, T_down, T_left,      L1_up, L1_right, L1_down, L1_left,      L2_up, L2_right, L2_down, L2_left};struct block{       int x[SIZE];       int y[SIZE];       type t;}; p;int stuck[SCREEN_WIDTH+1][SCREEN_HEIGHT+1];int points=0;/* Draw the borders around the game screen */void draw_borders(){     int i;     for(i=1;i<=SCREEN_HEIGHT;i++)     {          gotoxy(SCREEN_POSITION+1,i);          putch(BORDER);          gotoxy(2*SCREEN_WIDTH+SCREEN_POSITION+2,i);          putch(BORDER);     }     gotoxy(SCREEN_POSITION+1,SCREEN_HEIGHT+1);     for(i=1;i<=2*SCREEN_WIDTH+2; i++)     putch(BORDER);}/* Form the blocks */void block_form(block *p, int x, int y){     p->x[1]=x;     p->y[1]=y;          switch(p->t)     {                 case square:                                            p->x[0]=x-1; p->x[2]=x-1; p->x[3]=x;                      p->x[0]=y;   p->y[2]=y+1; p->y[3]=y+1;                                       break;                 case horizontal_long:                                            p->x[0]=x-1; p->x[2]=x+1; p->x[3]=x+2;                      p->y[0]=y;   p->y[2]=y;   p->y[3]=y;                                       break;                 case vertical_long:                                           p->x[0]=x;   p->x[2]=x;   p->x[3]=x;                          p->y[0]=y-1; p->y[2]=y+1; p->y[3]=y+2;                                       break;                                  case stair1:                                            p->x[0]=x-1; p->x[2]=x+1; p->x[3]=x;                      p->y[0]=y+1; p->y[2]=y;   p->y[3]=y+1;                                       break;                 case stair2:                                            p->x[0]=x-1; p->x[2]=x-1; p->x[3]=x;                      p->y[0]=y-1; p->y[2]=y;   p->y[3]=y+1;                                       break;                 case stair3:                                            p->x[0]=x-1; p->x[2]=x;   p->x[3]=x+1;                      p->y[0]=y-1; p->y[2]=y-1; p->y[3]=y;                                  break;                 case stair4:                                            p->x[0]=x+1; p->x[2]=x+1; p->x[3]=x;                      p->y[0]=y-1; p->y[2]=y;   p->[3]=y+1;                                  break;                                  case T_up:                                            p->x[0]=x;   p->x[2]=x-1 p->x[3]=x+1;                      p->y[0]=y-1; p->y[2]=y;  p->y[3]=y;                                       break;                 case T_right:                                            p->x[0]=x;   p->x[2]=x+1; p->x[3]=x;                      p->y[0]=y-1; p->y[2]=y;   p->y[3]=y+1;                                       break;                 case T_down:                                            p->x[0]=x-1; p->x[2]=x+1; p->x[3]=x;                      p->y[0]=y;   p->y[2]=y;   p->y[3]=y+1;                                       break;                 case T_left:                                            p->x[0]=x;   p->x[2]=x-1; p->x[3]=x;                      p->y[0]=y-1; p->y[2]=y;   p->y[3]=y+1;                                       break;                                  case L1_up:                                            p->x[0]=x;   p->x[2]=x;   p->x[3]=x+1;                      p->y[0]=y-1; p->y[2]=y+1; p->y[3]=y+1;                                       break;                 case L1_right:                                            p->x[0]=x-1; p->x[2]=x+1; p->x[3]=x-1;                      p->y[0]=y;   p->y[2]=y;   p->y[3]=y+1;                                       break;                 case L1_down:                                            p->x[0]=x-1; p->x[2]=x;   p->x[3]=x;                      p->y[0]=y-1; p->y[2]=y-1; p->y[3]=y+1;                                       break;                 case L1_left:                                            p->x[0]=x+1; p->x[2]=x-1; p->x[3]=x+1;                      p->y[0]=y-1; p->y[2]=y;   p->y[3]=y;                                       break;                                  case L2_up:                                            p->x[0]=x;   p->x[2]=x;   p->x[3]=x-1;                      p->y[0]=y-1; p->y[2]=y+1; p->y[3]=y+1;                                       break;                 case L2_right:                                            p->x[0]=x-1; p->x[2]=x-1; p->x[3]=x+1;                      p->y[0]=y-1; p->y[2]=y;   p->y[3]=y;                                       break;                 case L2_down:                                            p->x[0]=x;   p->x[2]=x+1; p->x[3]=x;                      p->y[0]=y-1; p->y[2]=y-1; p->y[3]=y+1;                                       break;                 case L2_left:                                            p->x[0]=x-1; p->x[2]=x+1; p->x[3]=x+1;                      p->y[0]=y;   p->y[2]=y;   p->y[3]=y+1;                                       break;                      }}/* There are 7 different blocks, and when we create a new one** to fall from the top, it can be any of these.*/void create_block(block *p){     switch(random(7))     {                      case 0: p->t=square;          break;                      case 1: p->t=horizontal_long; break;                      case 2: p->t=stair1;          break;                      case 3: p->t=stair3;          break;                      case 4: p->t=T_up;            break;                      case 5: p->t=L1_down;         break;                      case 6: p->t=L2_down;         break;     }     place_block(p, SCREEN_WIDTH/2,2);}/* delete_row() removes a full row from the game screen and** drops the rows above.*/void delete_row(int row){     int i,j;     for(j=row; j>1; j--)                for(i=1; i<=SCREEN_WIDTH; i++)                {                         stuck[i][j]=stuck[i][j-1];                         gotoxy(i*2+SCREEN_POSITION,j);                         if(stuck[i][j])                         {                             putch(BLOCK_CHARACTER);                             putch(BLOCK_CHARACTER);                         }                         else                         {                             putch(EMPTY_CHARACTER);                             putch(EMPTY_CHARACTER);                         }                }     points+=10;}/* freeze() locks the dropping block */void freeze(block *p){     int i,j,full_row;     for(i=0; i<SIZE; i++)              stuck[p->x[i]][p->y[i]]=1;     for(j=1; j<=SCREEN_HEIGHT; j++)     {              full_row=1;              for(i=1; i<=SCREEN_WIDTH; i++)                       if(!stuck[i][j]) full_row=0;              if(full_row) delete_row(j);     }}/* collision() checks if the dropping block is touching already** existing blocks, aka has it bumped into something.*/void collision(block *p){     int i,touch=0;     if(p->y[3]>SCREEN_HEIGHT) touch=1;     else for(i=0; i<SIZE; i++)     if(p->x[i]<1 || p->x[i]>SCREEN_WIDTH || stuck[p->x[i]][p->y[i]])     touch=1;     return touch;}void show(block *p, int char){     int i;     for(i=0; i<SIZE; i++)     {              gotoxy(p->x[i]*2+SCREEN_POSITION,p->y[i]);              putch(char);              putch(char);     }}/* a block is lowered by 1 row each round.** In the same time, we check if it has** bumped into anything, if so we freeze** it.*/int lower_block(block *p){    int i;    block temp_p=*p;    show(p, EMPTY_CHARACTER);    for(i=0; i<SIZE; i++) p->y[i]++;    if(collision(p))    {                    *p=temp_p;                    show(p, BLOCK_CHARACTER);                    freeze(p);                    if(p->y[0]<=2) exit(1);                    return 1;    }    show(p, BLOCK_CHARACTER);    return 0;}/* control_block() checks ie. that a block could not be** rotated if a part of it would go over the game** screen.*/void control_block(block *p, char command){     int i;     block temp_p=*p;     show(p, EMPTY_CHARACTER);     switch(command)     {                    case RIGHT:   for(i=0; i<SIZE; i++) p->x[i]++; break;                    case LEFT:    for(i=0; i<SIZE; i++) p->x[i]--; break;                    case ROTATE:  p->t=modification[p->t];                    place_block(p, p->x[1], p->y[1]);                    break;                    case END: exit(1);     }     if(collision(p)) *p=temp_p;     show(p, BLOCK_CHARACTER);}void main(){     int i,j,touch,speed=STARTSPEED;     randomize();     clrscr();     draw_borders();     for(j=0; j<=SCREEN_HEIGHT; j++)              for(i=0; i<=SCREEN_WIDTH; i++)                       stuck[i][j]=0;              while(1)              {                      gotoxy(50,5);                      printf("SCORE: %5d", points);                      create_block(&p);                      i=0;                      touch=0;                      do                      {                              if(kbhit())                              control_block(&p, getch());                              if((i=(i+1)%speed)==0)                              touch=lower_block(&p);                      }                      while(!touch);                      points++;                      if(speed>1) speed--;              }}