보드(게임판) 구성
 
앞에서 만든 7가지의 벽돌들이 놀 수 있는 Board(게임판)을 만들어 보겠습니다.
필요한 속성과 메소드는 다음과 같습니다.
| 속성 | 설명 | 
| COneBlock m_iBoard[BOARD_Y_SIZE+1][BOARD_X_SIZE+2] | Board 의 데이터 | 
| CClientDC *m_pDC; | 출력디바이스 | 
| CShape *m_Shape; | 움직이는 벽돌 포인터 | 
| CPoint m_ptOffsetDisplay; | 보드의 출력 옵셋 | 
| BOOL m_bGameStart; | 게임이 시작되었는가 | 
| CShapeArray m_arrayShape; | 벽돌을 array로 관리 | 
메소드는 다음과 같습니다.
| 메소드 | 설명 | 
| BOOL IsGameEnd(); | 게임이 끝났는지 확인 | 
| BOOL BlockDrop(); | 벽돌을 마지막 까지 내림 | 
| void RemoveLineDirect(int _line); | _line 번째 줄을 제거 | 
| void RemoveLine(); | 삭제할 수 있는 줄을 제거 | 
| void Refresh(BOOL bShape=TRUE); | 화면 갱신 | 
| void NewShape(); | 새로운 벽돌 생성 | 
| void NewGame(); | 새로운 게임 시작 | 
| void MergeNowBlock(); | 벽돌를 보드에 포함 | 
| BOOL BlockRotate(); | 벽돌 회전 | 
| BOOL BlockMoveRight(); | 벽돌 우측 이동 | 
| BOOL BlockMoveLeft(); | 벽돌 좌측 이동 | 
| BOOL BlockMoveDown(); | 벽돌 아래로 한 칸 이동 | 
| BOOL IsOverlap(CShape s); | 겹치는지 체크 | 
| void SetShape(CShape *_shape); | 벽돌 설정 | 
| void SetOffsetDisplay(CPoint _pt); | 화면 출력 옵셋 설정 | 
| void DrawOneBlock(int y,int x,int iSize,CClientDC *pDC, COLORREF crRGB, COLORREF crLine=RGB(255,255,255)) ; | 벽돌 그리기 | 
| void DrawBoard(BOOL bShape=TRUE); | 벽돌 그리기 | 
| void SetPDC(CClientDC *dc); | 출력 디바이스 설정 | 
Board.h
| 
 
 typedef CTypedPtrArray<CObArray, CShape*> CShapeArray; 
 class CBoard : public CObject { public: BOOL IsGameEnd(); BOOL BlockDrop(); void RemoveLineDirect(int _line); void RemoveLine(); void Refresh(BOOL bShape=TRUE); void NewShape(); void NewGame(); void MergeNowBlock(); BOOL BlockRotate(); BOOL BlockMoveRight(); BOOL BlockMoveLeft(); BOOL BlockMoveDown(); 
 BOOL IsOverlap(CShape s); void SetShape(CShape *_shape); void SetOffsetDisplay(CPoint _pt); 
 void DrawOneBlock(int y,int x,int iSize,CClientDC *pDC, COLORREF crRGB, COLORREF crLine=RGB(255,255,255)) ; void DrawBoard(BOOL bShape=TRUE); void SetPDC(CClientDC *dc); 
 CShapeArray m_arrayShape; // 벽돌들을 array로 관리 CClientDC *m_pDC; COneBlock m_iBoard[BOARD_Y_SIZE+1][BOARD_X_SIZE+2]; CShape *m_Shape; CPoint m_ptOffsetDisplay; // 보드의 옵셋 BOOL m_bGameStart; 
 CBoard(); virtual ~CBoard(); 
 }; | 
Board.cpp
| 
 
 CBoard::CBoard() { m_Shape = NULL; m_bGameStart = false; 
 m_ptOffsetDisplay = CPoint(0,0); 
 
 // 랜덤 벽돌을 위한 함수 srand( (unsigned)time( NULL ) ); 
 
 m_arrayShape.Add(new CShape1()); m_arrayShape.Add(new CShape2()); m_arrayShape.Add(new CShape3()); m_arrayShape.Add(new CShape4()); m_arrayShape.Add(new CShape5()); m_arrayShape.Add(new CShape6()); m_arrayShape.Add(new CShape7()); NewGame(); 
 } 
 CBoard::~CBoard() { if(m_Shape) { delete m_Shape; m_Shape = NULL; } } 
 void CBoard::SetPDC(CClientDC *dc) { m_pDC = dc; m_Shape->SetPDC(dc); } 
 void CBoard::DrawBoard(BOOL bShape) { int tempY; 
 for(tempY = 0;tempY<BOARD_Y_SIZE+1;tempY++){ for(int tempX=0; tempX<BOARD_X_SIZE+2; tempX++) { if(0 != m_iBoard[tempY][tempX].m_iValue){ DrawOneBlock((m_ptOffsetDisplay.y+tempY),m_ptOffsetDisplay.x+tempX,ONE_BLOCK_SIZE,m_pDC,RGB(200,200,200)); 
 } } } 
 if(m_Shape) { m_Shape->SetPDC(m_pDC); m_Shape->DrawBlock(); 
 } } 
 
 void CBoard::DrawOneBlock(int y,int x,int iSize,CClientDC *pDC, COLORREF crRGB, COLORREF crLine) { pDC->FillSolidRect((x)*iSize, (y)*iSize, iSize, iSize, crRGB); pDC->Draw3dRect((x)*iSize, (y)*iSize, iSize, iSize, crLine,crLine); } 
 
 void CBoard::SetOffsetDisplay(CPoint _pt) { this->m_ptOffsetDisplay = _pt; m_Shape->SetOffsetDisplay(_pt); } 
 
 void CBoard::SetShape(CShape *_shape) { this->m_Shape = _shape; } 
 
 void CBoard::NewGame() { int tempY; int tempX; 
 for(tempY = 0;tempY<BOARD_Y_SIZE+1;tempY++){ for(tempX=0; tempX<BOARD_X_SIZE+2; tempX++) { m_iBoard[tempY][tempX].m_iValue = 0; } } 
 
 // 보드의 좌측 벽 for(int i=0;i<BOARD_Y_SIZE;i++){ m_iBoard[i][0].m_iValue=50; } 
 // 보드의 우측 벽 for( i=0;i<BOARD_Y_SIZE;i++){ m_iBoard[i][BOARD_X_SIZE+1].m_iValue=50; } 
 // 보드의 하단 벽 for( i=0;i<BOARD_X_SIZE+2;i++){ m_iBoard[BOARD_Y_SIZE][i].m_iValue=50; } 
 
 NewShape(); 
 } 
 BOOL CBoard::BlockMoveDown() { CShape s; s.Copy(m_Shape); 
 s.m_ptPosition.y++; if(IsOverlap(s)) { // LOGOUT(" 겹친다."); MergeNowBlock(); RemoveLine(); NewShape(); Refresh(); 
 return FALSE; } else { // LOGOUT(" 안 겹친다."); m_Shape->MoveDown(); 
 return TRUE; } } 
 BOOL CBoard::BlockMoveLeft() { CShape s; s.Copy(m_Shape); 
 s.m_ptPosition.x--; if(IsOverlap(s)) { return FALSE; 
 } else { m_Shape->MoveLeft(); return TRUE; 
 } } 
 BOOL CBoard::BlockMoveRight() { CShape s; s.Copy(m_Shape); 
 s.m_ptPosition.x++; if(IsOverlap(s)) { return FALSE; } else { m_Shape->MoveRight(); return TRUE; 
 } } 
 BOOL CBoard::BlockRotate() { CShape s; s.Copy(m_Shape); 
 s.ChangeRotate(); if(IsOverlap(s)) { return FALSE; } else { m_Shape->RotateCCW(); return TRUE; 
 } } 
 BOOL CBoard::BlockDrop() { while(BlockMoveDown()) { 
 } return true; } 
 
 BOOL CBoard::IsOverlap(CShape s) { for (int iTemp = 0;iTemp<4;iTemp++) { COneBlock b =s.GetOneBlock(s.GetRotate(),iTemp); 
 int x = s.m_ptPosition.x + b.iPosX; int y = s.m_ptPosition.y+ b.iPosY; 
 if(0 != m_iBoard[y][x].m_iValue){ return TRUE; 
 
 } } return FALSE;} 
 
 void CBoard::MergeNowBlock() { 
 for (int iTemp = 0;iTemp<4;iTemp++) { COneBlock b =m_Shape->GetOneBlock(m_Shape->GetRotate(),iTemp); 
 int x = m_Shape->m_ptPosition.x + b.iPosX; int y = m_Shape->m_ptPosition.y+ b.iPosY; 
 m_iBoard[y][x].m_iValue = 50; 
 } } 
 
 void CBoard::RemoveLine() { int p[4];// m_Shape->GetY(p); 
 for (int iTemp = 0;iTemp<4;iTemp++) { int iLineY = p[iTemp]; if (-1 != iLineY) { BOOL bGoodOneLine = TRUE; for (int iTempBlockX = 0;iTempBlockX<BOARD_X_SIZE+2;iTempBlockX++) { if(0 == m_iBoard[iLineY][iTempBlockX].m_iValue ){ // 한칸이라도 빈칸이 있으면. bGoodOneLine = FALSE; } } 
 if(TRUE == bGoodOneLine){ RemoveLineDirect(iLineY); 
 for(int iTempLine = 0;iTempLine<4;iTempLine++) { if(-1 !=p[iTempLine] && p[iTempLine]<iLineY) { 
 p[iTempLine]++; } } p[iTemp] = -1; } } } } 
 void CBoard::NewShape() { int iShape = rand()%m_arrayShape.GetSize(); m_Shape = m_arrayShape.GetAt(iShape); 
 
 m_Shape->m_ptPosition = CPoint(4,0); m_Shape->SetOffsetDisplay(m_ptOffsetDisplay); } 
 void CBoard::Refresh(BOOL bShape) { int tempY; 
 for(tempY = 0;tempY<BOARD_Y_SIZE+1;tempY++){ for(int tempX=0; tempX<BOARD_X_SIZE+2; tempX++) { DrawOneBlock((m_ptOffsetDisplay.y+tempY),m_ptOffsetDisplay.x+tempX,ONE_BLOCK_SIZE,m_pDC,RGB(0xc0,0xc0,0xc0),RGB(0xc0,0xc0,0xc0)); 
 } } 
 DrawBoard(bShape); } 
 void CBoard::RemoveLineDirect(int _line) { while(_line >1) { LOGOUT("_line:%d",_line); for(int j=1;j<BOARD_X_SIZE+1;j++){ m_iBoard[_line][j] =m_iBoard[_line-1][j] ; m_iBoard[_line-1][j].m_iValue = 0; 
 } _line-- ; } Refresh(FALSE); } 
 
 BOOL CBoard::IsGameEnd() { for(int tempY = 0;tempY<2 ;tempY++){ for(int tempX=3; tempX<7; tempX++) { if(0 != m_iBoard[tempY][tempX].m_iValue){ return TRUE; } } } 
 return FALSE; } | 

 
	
		 


 
    
 
    
 
     

 2
2
보드 그리기에서 보드 중간 중간에 블록을 처음부터 만들수는 없는건가요
예를들어
ㅁ ㅁ
ㅁ ㅁ
ㅁ ㅁ
ㅁ ㅁ
ㅁ ㅁ ㅁ ㅁ ㅁ
ㅁ ㅁ ㅁ ㅁ
ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ
(ㅁ = 블록)
이런 식으로 그릴려고 하는데.. 어떻게해야할지 감이 안잡혀서요