C++러시아 블록 만 들 기

18325 단어 C++러시아 블록
인연:
Codeblocks 가 가지 고 있 는 러시아 블록 을 놀 때 는 좋 지만 시간 제한 이 있 습 니 다.그래서 혼자 하나 더 쓰 려 고요.
프로그램 효과:

주요 내용:
프로그램 에 표시 할 부분 도 있 고 표시 되 지 않 는 부분 도 있 습 니 다.표시 되 지 않 는 부분 은 모두 1 을 저장 합 니 다.
다음 그림:

shape 는 4*4 배열(shape)로 저장 합 니 다.예:
    0 0 0 0
    0 1 0 0
    1 1 1 0
    0 0 0 0
또한 변수 row 와 column 으로 shape 배열 의 왼쪽 상단 이 board 에 있 는 위 치 를 저장 합 니 다.
매번 떨 어 지 거나 좌우 로 이동 할 때마다 row 와 column 을 변경 한 다음 현재 row 와 column 에서 shape 가 1 칸 으로 겹 쳤 는 지 확인 합 니 다.겹 치면 shape 가 아웃 되 었 거나 가장 낮은 곳 에 도 착 했 는 지 확인 하고 row 와 column 값 을 회복 해 야 합 니 다.또 행방 이 라면 셰 이 프 를 보드 위 에 올 려 놓 고 새로운 셰 이 프 를 만들어 야 한다.
회전 할 때 먼저 shape 배열 을 회전 시 킨 다음 에 겹 치 는 것 을 검 측 하고 겹 치 는 것 이 있 으 면 반대로 회전 합 니 다.
코드:

#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif

#include <tchar.h>
#include <windows.h>
#include <pthread.h>
#include <stdio.h>
#include <time.h>
/*-----------------   --------------------------------------------------------*/
#define WIDTH 180
#define HEIGHT 400
#define LONG_SLEEP 300
#define BKCOLOR RGB(238,238,238)//   
/*-----------------  ----------------------------------------------------------*/
static int shapes[7][4][4];//  7   
static int high_score[4]= {0,0,0,0};//          ,            
static int **shape;//    
static int **board;
static int M=15;//     
static int N=30;//     
static int MM=M+8;//board   
static int NN=N+4;//board   
static int LEFT=4;//       
static int RIGHT=LEFT+M-1;//       
static int TOP=0;//       
static int BOTTOM=N-1;//       
static int score=0;
static int row=0;//     
static int column=MM/2;//     
static bool is_pause=false;
static HBRUSH grey_brush =CreateSolidBrush (RGB(210,210,210));
static HBRUSH white_brush =CreateSolidBrush (RGB(130,130,130));
static HBRUSH bk_brush =CreateSolidBrush (BKCOLOR);
static HPEN hPen = CreatePen(PS_SOLID,1,RGB(147,155,166));
static int lattices_top=40;//    
static int lattices_left=20;//    
static int width=WIDTH/M;//       
static int height=(HEIGHT-lattices_top)/N;//       
/*-----------------  -----------------------------------------------------------*/
void add_score() ;
bool check_is_lose() ;
void clear_up() ;//         
void* down_thread_function(void * args) ;//            
void exit_game(HWND hwnd) ;
void give_new_shape() ;//         
int handle_key(HWND hwnd,WPARAM wParam) ;
int init_down_thread(HWND hwnd) ;//         
int init_game(HWND hwnd) ;//       
void init_play() ;//       
bool is_legel() ;//             (           )
int load_scores(int* a) ;//         
int load_shape() ;//      7   
void lose_game(HWND hwnd) ;
int move_down(HWND hwnd) ;//    
int move_lr(HWND hwnd,int lr) ;//      
void paint_lattice(HDC hdc,int x,int y,int color) ;//      
void paint_UI(HDC hdc) ;//   
void reset_rc() ;
void rerotate_matrix(int mn) ;//           mn   
void rotate_matrix(int mn) ;//           mn   
int rotate_shape(HWND hwnd) ;//           
bool save_score(HWND hwnd) ;//       
void shape_to_ground() ;//        ,  board
bool sort_scores(int* a) ;//           ,         true
void update_UI(HWND hwnd) ;//    ,   Rect  (        ) 
void update_UI_all(HWND hwnd) ;//    ,      
int write_scores(int* a) ;//      




/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/* Make the class name into a global variable */
TCHAR szClassName[ ] = _T("Tris");

int WINAPI WinMain (HINSTANCE hThisInstance,
          HINSTANCE hPrevInstance,
          LPSTR lpszArgument,
          int nCmdShow) {
  HWND hwnd;        /* This is the handle for our window */
  MSG messages;      /* Here messages to the application are saved */
  WNDCLASSEX wincl;    /* Data structure for the windowclass */

  /* The Window structure */
  wincl.hInstance = hThisInstance;
  wincl.lpszClassName = szClassName;
  wincl.lpfnWndProc = WindowProcedure;   /* This function is called by windows */
  wincl.style = CS_DBLCLKS;         /* Catch double-clicks */
  wincl.cbSize = sizeof (WNDCLASSEX);

  /* Use default icon and mouse-pointer */
  wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
  wincl.lpszMenuName = NULL;         /* No menu */
  wincl.cbClsExtra = 0;           /* No extra bytes after the window class */
  wincl.cbWndExtra = 0;           /* structure or the window instance */
  /* Use Windows's default colour as the background of the window */
  wincl.hbrBackground =bk_brush;
  /* Register the window class, and if it fails quit the program */
  if (!RegisterClassEx (&wincl))
    return 0;

  /* The class is registered, let's create the program*/
  hwnd = CreateWindowEx (
        0,          /* Extended possibilites for variation */
        szClassName,     /* Classname */
        _T("Tris"),    /* Title Text */
        WS_OVERLAPPEDWINDOW, /* default window */
        CW_USEDEFAULT,    /* Windows decides the position */
        CW_USEDEFAULT,    /* where the window ends up on the screen */
        WIDTH+200,         /* The programs width */
        HEIGHT+70,         /* and height in pixels */
        HWND_DESKTOP,    /* The window is a child-window to desktop */
        NULL,        /* No menu */
        hThisInstance,    /* Program Instance handler */
        NULL         /* No Window Creation data */
      );

  /* Make the window visible on the screen */
  ShowWindow (hwnd, nCmdShow);

  /* Run the message loop. It will run until GetMessage() returns 0 */
  while (GetMessage (&messages, NULL, 0, 0)) {
    /* Translate virtual-key messages into character messages */
    TranslateMessage(&messages);
    /* Send message to WindowProcedure */
    DispatchMessage(&messages);
  }

  /* The program return-value is 0 - The value that PostQuitMessage() gave */
  return messages.wParam;
}
//      7   
int load_shape() {
  FILE* f=fopen("shapes.txt","rb");
  if(f==NULL) {
    return -1;
  }
  for(int i=0; i<7; i++) {
    for(int j=0; j<4; j++) {
      for(int k=0; k<4; k++) {
        if(fscanf(f,"%d",&shapes[i][j][k])!=1) {
          return -1;
        }
      }
    }
  }
  fclose(f);
  return 0;
}
//         
void give_new_shape() {
  int shape_num=rand()%7;
  for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      shape[i][j]=shapes[shape_num][i][j];
    }
  }
}
void add_score() {
  score+=100;
}
//         
void clear_up() {
  for(int i=row; i<=row+3; i++) {
    if(i>BOTTOM)continue;
    bool there_is_blank=false;
    for(int j=LEFT; j<=RIGHT; j++) {
      if(board[i][j]==0) {
        there_is_blank=true;
        break;
      }
    }
    if(!there_is_blank) {
      add_score();
      for(int r=i; r>=1; r--) {
        for(int c=LEFT; c<=RIGHT; c++) {
          board[r][c]=board[r-1][c];
        }
      }
    }
  }
}
//             (           )
bool is_legel() {
  for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      if(shape[i][j]==1&&board[row+i][column+j]==1) {
        return false;
      }
    }
  }
  return true;
}
//           mn   
void rotate_matrix(int mn) {
  int** a=shape;
  int s=0;
  for(int n=mn; n>=1; n-=2) {
    for(int i=0; i<n-1; i++) {
      int t=a[s+i][s];
      a[s+i][s]=a[s][s+n-i-1];
      a[s][s+n-i-1]=a[s+n-i-1][s+n-1];
      a[s+n-i-1][s+n-1]=a[s+n-1][s+i];
      a[s+n-1][s+i]=t;
    }
    s++;
  }
}
//           mn   
void rerotate_matrix(int mn) {
  int** a=shape;
  int s=0;
  for(int n=mn; n>=1; n-=2) {
    for(int i=0; i<n-1; i++) {
      int t=a[s+i][s];
      a[s+i][s]=a[s+n-1][s+i];
      a[s+n-1][s+i]=a[s+n-i-1][s+n-1];
      a[s+n-i-1][s+n-1]=a[s][s+n-i-1];
      a[s][s+n-i-1]=t;
    }
    s++;
  }
}
//      
void paint_lattice(HDC hdc,int x,int y,int color) {
  if(x<TOP||x>BOTTOM||y<LEFT||y>RIGHT) {
    return ;
  }
  x-=TOP;
  y-=LEFT;
  int left=lattices_left+y*width;
  int right=lattices_left+y*width+width;
  int top=lattices_top+x*height;
  int bottom=lattices_top+x*height+height;
  MoveToEx (hdc,left,top, NULL) ;
  LineTo (hdc,right,top) ;
  MoveToEx (hdc,left,top, NULL) ;
  LineTo (hdc,left,bottom) ;
  MoveToEx (hdc,left,bottom, NULL) ;
  LineTo (hdc,right,bottom) ;
  MoveToEx (hdc,right,top, NULL) ;
  LineTo (hdc,right,bottom) ;
  SelectObject(hdc, grey_brush);
  if(color==0) {
    SelectObject(hdc, white_brush);
  }
  Rectangle(hdc,left,top,right,bottom);
}
//    ,   Rect  (        ) 
void update_UI(HWND hwnd) {
  static RECT rect;
  rect.left=lattices_left;
  rect.right=lattices_left+M*width+width;
  rect.top=lattices_top+(row-1)*height;
  rect.bottom=lattices_top+(row+4)*height;
  InvalidateRect (hwnd,&rect, false) ;
}
//    ,      
void update_UI_all(HWND hwnd) {
  InvalidateRect (hwnd,NULL, false) ;
}
//   
void paint_UI(HDC hdc) {
  SetBkColor(hdc,BKCOLOR);
  SelectObject(hdc,hPen); //    
  char score_str[20];
  sprintf(score_str,"Score:%d",score);
  TextOut(hdc,10,10,score_str,strlen(score_str));
  sprintf(score_str,"Highest Scores:");
  TextOut(hdc,WIDTH+50,50,score_str,strlen(score_str));
  for(int i=0; i<3; i++) {
    sprintf(score_str,"%d",high_score[i]);
    TextOut(hdc,WIDTH+50,50+(i+1)*20,score_str,strlen(score_str));
  }
  for(int i=TOP; i<=BOTTOM; i++) {
    for(int j=LEFT; j<=RIGHT; j++) {
      paint_lattice(hdc,i,j,board[i][j]);
    }
  }
  for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      if(shape[i][j]==1)
        paint_lattice(hdc,row+i,column+j,shape[i][j]);
    }
  }
}
//           
int rotate_shape(HWND hwnd) {
  int mn=4;
  rotate_matrix(mn);
  if(!is_legel()) {
    rerotate_matrix(mn);
  }
  update_UI(hwnd);
}
void reset_rc() {
  row=0;
  column=MM/2-2;
}
//         
int load_scores(int* a) {
  FILE* f=fopen("scores.txt","r");
  if(f==NULL)return -1;
  fscanf(f,"%d%d%d",&a[0],&a[1],&a[2]);
  return 0;
}
//       
void init_play() {
  load_scores(high_score);
  for(int i=0; i<NN; i++) {
    for(int j=0; j<MM; j++) {
      board[i][j]=0;
    }
  }
  for(int i=0; i<N; i++) {
    for(int j=0; j<LEFT; j++) {
      board[i][j]=1;
    }
  }
  for(int i=0; i<N; i++) {
    for(int j=RIGHT+1; j<MM; j++) {
      board[i][j]=1;
    }
  }
  for(int i=BOTTOM+1; i<NN; i++) {
    for(int j=0; j<MM; j++) {
      board[i][j]=1;
    }
  }
  reset_rc();
  score=0;
  give_new_shape();
  is_pause=false;
  return ;
}
bool check_is_lose() {
  if(row==0)return true;
  return false;
}
//           ,         true
bool sort_scores(int* a) {
  int temp=a[3];
  for(int i=0; i<4; i++) {
    for(int j=0; j<3; j++) {
      if(a[j]<a[j+1]) {
        int t=a[j];
        a[j]=a[j+1];
        a[j+1]=t;
      }
    }
  }
  if(temp>a[3])return true;
  return false;
}
//      
int write_scores(int* a) {
  FILE* f=fopen("scores.txt","w");
  if(f==NULL)return -1;
  fprintf(f,"%d
%d
%d
",a[0],a[1],a[2]); return 0; } // bool save_score(HWND hwnd) { high_score[3]=score; bool made_record=sort_scores(high_score); if(write_scores(high_score)!=0) { MessageBox(hwnd,"Write file error.Program will exit.","Error",NULL); DestroyWindow(hwnd); } return made_record; } void lose_game(HWND hwnd) { if(is_pause)return ; is_pause=true; char message[200]="You lose the Game.
"; char title[50]="Game Over"; if(save_score(hwnd)) { strcat(message,"You have made a new record.
"); char score_str[100]; sprintf(score_str,"The Highest Scores:
%d
%d
%d
",high_score[0],high_score[1],high_score[2]); strcat(message,score_str); } strcat(message,"
Play again?
"); if(MessageBox(hwnd,message,title,MB_YESNO)==IDYES) { init_play(); update_UI_all(hwnd); } else { exit(0); } } void exit_game(HWND hwnd) { is_pause=true; char message[200]=""; char title[50]="Exit"; if(save_score(hwnd)) { strcat(message,"You have made a new record.
"); char score_str[100]; sprintf(score_str,"The Highest Scores:
%d
%d
%d
",high_score[0],high_score[1],high_score[2]); strcat(message,score_str); MessageBox(hwnd,message,title,NULL); } exit(0); } // , board void shape_to_ground() { for(int i=0; i<4; i++) { for(int j=0; j<4; j++) { board[row+i][column+j]=shape[i][j]==1?1:board[row+i][column+j]; } } } // int move_down(HWND hwnd) { row++; if(!is_legel()) { row--; if(check_is_lose()) { lose_game(hwnd); return 0; } shape_to_ground(); clear_up(); update_UI_all(hwnd); reset_rc(); give_new_shape(); } update_UI(hwnd); } // struct thread_arg { HWND arg_hwnd; }; // void* down_thread_function(void * args) { thread_arg *arg=(thread_arg*)args; HWND dhwnd=arg->arg_hwnd; while(true) { if(is_pause) { Sleep(300); continue; } move_down(dhwnd); Sleep(LONG_SLEEP); } } // int init_down_thread(HWND hwnd) { int ret; pthread_t t; thread_arg *argp=new thread_arg; argp->arg_hwnd=hwnd; ret=pthread_create(&t,NULL,down_thread_function,argp); delete argp; if(ret!=0) { return -1; } return 0; } // int init_game(HWND hwnd) { board=new int*[NN]; for(int i=0; i<NN; i++) { board[i]=new int[MM]; } shape=new int*[4]; for(int i=0; i<4; i++) { shape[i]=new int[4]; } srand(time(0)); if(load_shape()!=0) { MessageBox(hwnd,"Read file error.Program will exit.","Error",NULL); exit(-1); } init_play(); update_UI_all(hwnd); if(init_down_thread(hwnd)!=0) { MessageBox(hwnd,"Thread error.Program will exit.","Error",NULL); exit(-1); } return 0; } // int move_lr(HWND hwnd,int lr) { int temp=column; if(lr==0)column--; else { column++; } if(!is_legel()) { column=temp; } update_UI(hwnd); } int handle_key(HWND hwnd,WPARAM wParam) { if(wParam==VK_ESCAPE) {//ESC exit_game(hwnd); } if(wParam==VK_SPACE) {// is_pause=!is_pause; } if(is_pause==true) { Sleep(300); return 0; } if(wParam==VK_UP) { rotate_shape(hwnd); } if(wParam==VK_DOWN) { move_down(hwnd); } if(wParam==VK_LEFT) { move_lr(hwnd,0); } if(wParam==VK_RIGHT) { move_lr(hwnd,1); } return 0; } /* This function is called by the Windows function DispatchMessage() */ HWND hwnd; LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hdc; static HDC hdcBuffer; static HBITMAP hBitMap; static PAINTSTRUCT ps ; switch (message) { /* handle the messages */ case WM_CREATE: init_game(hwnd); break; case WM_KEYDOWN: handle_key(hwnd,wParam); break; case WM_DESTROY: exit_game(hwnd); PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; paint_UI(hdc); EndPaint (hwnd, &ps) ; break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }

좋은 웹페이지 즐겨찾기