#include #include // winmm.lib をリンクする #pragma comment(lib,"winmm") // エラー #define ERR -1 // ピースの横と縦のマス数 #define PIECE_WIDTH 4 #define PIECE_HEIGHT 4 /* フィールドの横と縦のマス数 */ #define FIELD_WIDTH 14 #define FIELD_HEIGHT 24 // マスのピクセル数 #define CELL_WIDTH 20 #define CELL_HEIGHT 20 /* MovePiece 関数の引数 */ #define PIECE_LEFT 2 #define PIECE_RIGHT 4 #define PIECE_DOWN 8 BYTE field[FIELD_WIDTH][FIELD_HEIGHT]={0}; /* ゲームフィールド */ DWORD fColor[FIELD_WIDTH][FIELD_HEIGHT]={0}; // ゲームフィールドの色 BYTE piece[PIECE_WIDTH][PIECE_HEIGHT]={0}; /* 現在移動中のブロック */ DWORD pColor[PIECE_WIDTH][PIECE_HEIGHT]={0}; // 現在移動中のブロックの色 POINT location={0,0}; /* 現在移動中のブロックの位置 */ BYTE next[PIECE_WIDTH][PIECE_HEIGHT]={0}; // 次のブロック DWORD nColor[PIECE_WIDTH][PIECE_HEIGHT]={0}; // 次のブロックの色 DWORD score=0; // 獲得点数 DWORD playTime=0; // プレイ時間 BOOL GameOver=FALSE; // TRUE となるのはゲームオーバーからリプレイするまで #define MUTEX_NAME "MutexObject of SPACE TETRIS" // ミューテックスオブジェクトの名前 #define WM_MUTEX WM_APP // メインスレッドにミューテックスの所有権取得を要求するメッセージ /* piece[][] 内のブロックの最上部の位置を返す */ int GetPieceTop(void) { for(int y=0;y=0;y--){ for(int x=0;x=0;x--){ for(int y=0;y=0 , (location.y)+y>=0 for(x=0;x=0 && (location.y)+y>=0 && field[(location.x)+x-1][(location.y)+y]){ // 一つ左にブロックがある return FALSE; } } } location.x--; return TRUE; case PIECE_RIGHT: right=GetPieceRight(); if((location.x)+right >= FIELD_WIDTH-1) return FALSE; for(y=0;y=0 for(x=0;x=0 && field[(location.x)+x+1][(location.y)+y]){ // 一つ右にブロックがある return FALSE; } } } location.x++; return TRUE; case PIECE_DOWN: bottom=GetPieceBottom(); if((location.y)+bottom >= FIELD_HEIGHT-1) return FALSE; for(y=0;y=0 , (location.y)+y+1=0 && (location.y)+y+1=FIELD_WIDTH || offsetY>=FIELD_HEIGHT // ↓offsetY>=0 は添字の有効性を調べている || (offsetY>=0 && field[offsetX][offsetY])){ //既にブロックがある return FALSE; } } } } for(y=0;y=0;y--){ int lineCount=0; for(x=0;x=0 && delCount>0; ){ int lineCount=0; for(x=0;x=0;iy--){ for(x=0;x=0){ field[x][iy]=field[x][iy-1]; fColor[x][iy]=fColor[x][iy-1]; }else{ field[x][0]=0; /* 0 行より上はないので 0 で埋める */ fColor[x][0]=0; } } } } } // 次のブロックをあらかじめ作っておく void CreatePiece(void) { for(int y=0;y=0 は添字の有効性を調べている if(piece[x][y] && (location.y)+y>=0){ field[(location.x)+x][(location.y)+y]=piece[x][y]; fColor[(location.x)+x][(location.y)+y]=pColor[x][y]; } } } } // 動作制御スレッド DWORD WINAPI ThreadProc(LPVOID lpParameter) // lpParameter:ウィンドウのハンドル { HWND hWnd=(HWND)lpParameter; HANDLE hMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,MUTEX_NAME); DWORD beforeTime=timeGetTime(); DWORD sleep=1000; DWORD minute=0; DWORD progress,signal=1; int x,y,line; while(1){ // ↓メインスレッドからの介入がない限り progress=timeGetTime()-beforeTime; // タイムアウトによって待機を解除する if(progress=60*1000 && sleep>100){ sleep-=100; // 一分ごとに待機時間を減らしてゆく minute=0; } beforeTime=timeGetTime(); if(!MovePiece(PIECE_DOWN)){ // 現在移動中のブロックが下段に達したら↓ PieceToField(); line=DeleteLine(); if(line>0){ for(y=0;y