안녕하세요
테트리스 강의 잘봤습니다.
거의 따라서 해보고 몇개 명칭만 좀 바꿔보고 했는데요.
첫판은 잘됩니다.
한판이 무사히 끝나고 다시 시작했을때
블록을 2개째 깰때부터 실행이 이상하게 안되는데요
혹시 이유를 알수 없을까요?.
블록도 이상하게 깨지는것같긴 합니다만... 도와주세요. ㅠ
밑에는 소스입니다.
// Tetris84View.cpp : implementation of the CTetris84View class
//
#include "stdafx.h"
#include "Tetris84.h"
#include "Tetris84Doc.h"
#include "Tetris84View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int timer=1000;
int g_BoardInfo[BOARD_Y_SIZE+1][BOARD_X_SIZE+2];//Board정보 선언
int g_NowBlockInfo[7][4][4][4]={//1번째 열은 모양 담당[7가지],2번째열은 [4가지] 회전 담당이므로 4(90도씩 회전)
 {//아래로 첫번째 블록
  {
   {0,1,0,0},
   {0,1,0,0},
   {0,1,0,0},
   {0,1,0,0}
  },
  {
   {0,0,0,0},
   {0,0,0,0},
   {1,1,1,1},
   {0,0,0,0}
  },
  {
   {0,0,1,0},
   {0,0,1,0},
   {0,0,1,0},
   {0,0,1,0}
  },
  {
   {0,0,0,0},
   {1,1,1,1},
   {0,0,0,0},
   {0,0,0,0}
  }
 }, 
 { //아래로 2번째 벽돌 
  {
   {1,1,0,0},
   {1,1,0,0},
   {0,0,0,0},
   {0,0,0,0}
  },
  {
   {1,1,0,0},
   {1,1,0,0},
   {0,0,0,0},
   {0,0,0,0}
  },
  {
   {1,1,0,0},
   {1,1,0,0},
   {0,0,0,0},
   {0,0,0,0}
  },
  {
   {1,1,0,0},
   {1,1,0,0},
   {0,0,0,0},
   {0,0,0,0}
  }
 },
 {//아래로 3번째 블록
  {
   {1,0,0,0},
   {1,1,0,0},
   {1,0,0,0},
   {0,0,0,0}
  },
  {
   {0,1,0,0},
   {1,1,1,0},
   {0,0,0,0},
   {0,0,0,0}
  },
  {
   {0,1,0,0},
   {1,1,0,0},
   {0,1,0,0},
   {0,0,0,0}
  },
  {
   {1,1,1,0},
   {0,1,0,0},
   {0,0,0,0},
   {0,0,0,0}
  }
 },
 {//아래로 4번째 블록
  {
   {1,1,0,0},
   {1,0,0,0},
   {1,0,0,0},
   {0,0,0,0}
  },
  {
   {1,0,0,0},
   {1,1,1,0},
   {0,0,0,0},
   {0,0,0,0}
  },
  {
   {0,1,0,0},
   {0,1,0,0},
   {1,1,0,0},
   {0,0,0,0}
  },
  {
   {1,1,1,0},
   {0,0,1,0},
   {0,0,0,0},
   {0,0,0,0}
  }
 },
 {//아래로 5번째 블록
  {
   {1,0,0,0},
   {1,0,0,0},
   {1,1,0,0},
   {0,0,0,0}
  },
  {
   {0,0,1,0},
   {1,1,1,0},
   {0,0,0,0},
   {0,0,0,0}
  },
  {
   {1,1,0,0},
   {0,1,0,0},
   {0,1,0,0},
   {0,0,0,0}
  },
  {
   {1,1,1,0},
   {1,0,0,0},
   {0,0,0,0},
   {0,0,0,0}
  }
 },
 {//아래로 6번째 블록
  {
   {0,1,0,0},
   {1,1,0,0},
   {1,0,0,0},
   {0,0,0,0}
  },
  {
   {1,1,0,0},
   {0,1,1,0},
   {0,0,0,0},
   {0,0,0,0}
  },
  {
   {0,1,0,0},
   {1,1,0,0},
   {1,0,0,0},
   {0,0,0,0}
  },
  {
   {1,1,0,0},
   {0,1,1,0},
   {0,0,0,0},
   {0,0,0,0}
  }
 },
 {//아래로 7번째 블록
  {
   {1,0,0,0},
   {1,1,0,0},
   {0,1,0,0},
   {0,0,0,0}
  },
  {
   {0,1,1,0},
   {1,1,0,0},
   {0,0,0,0},
   {0,0,0,0}
  },
  {
   {1,0,0,0},
   {1,1,0,0},
   {0,1,0,0},
   {0,0,0,0}
  },
  {
   {0,1,1,0},
   {1,1,0,0},
   {0,0,0,0},
   {0,0,0,0}
  }
 }
};
/////////////////////////////////////////////////////////////////////////////
// CTetris84View
IMPLEMENT_DYNCREATE(CTetris84View, CFormView)
BEGIN_MESSAGE_MAP(CTetris84View, CFormView)
 //{{AFX_MSG_MAP(CTetris84View)
// ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
 ON_WM_PAINT()//PAINT함수 가동
 ON_WM_TIMER()//TIMER함수 가동 
 //}}AFX_MSG_MAP
 // Standard printing commands
 ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTetris84View construction/destruction
CTetris84View::CTetris84View()//기존 x좌표 값, y좌표,Block 값 초기화 
 : CFormView(CTetris84View::IDD)
{
 //{{AFX_DATA_INIT(CTetris84View)
  // NOTE: the ClassWizard will add member initialization here
 //}}AFX_DATA_INIT
 // TODO: add construction code here
 m_iNowBlockTurn = 0;//블록회전 하는 모양을 나타내는 변수를 초기화
 m_iNowBlockShape = 0; //블록모양을 나타내는 변수를 초기화
    m_iNowBlockX=5;
 m_iNowBlockY=4; //Block의 기존 위치 X,Y좌표 값들 
 m_iOneBlockSize=30;//Block의 크기 
 int i;
 for(i=0;i<BOARD_Y_SIZE;i++)
 {
  g_BoardInfo[i][0]=50;
 }//보드의 좌측벽 
 for(i=0;i<BOARD_Y_SIZE;i++)
 {
  g_BoardInfo[i][BOARD_X_SIZE+1]=50;
 }//보드의 우측벽
 for(i=0;i<BOARD_X_SIZE;i++)
 {
  g_BoardInfo[BOARD_Y_SIZE][i]=50;
 }//보드의 3하단벽 
}
CTetris84View::~CTetris84View()
{
}
void CTetris84View::DoDataExchange(CDataExchange* pDX)
{
 CFormView::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CTetris84View)
  // NOTE: the ClassWizard will add DDX and DDV calls here
 //}}AFX_DATA_MAP
}
BOOL CTetris84View::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs
 return CFormView::PreCreateWindow(cs);
}
void CTetris84View::OnInitialUpdate()
{
 CFormView::OnInitialUpdate();
 GetParentFrame()->RecalcLayout();
 ResizeParentToFit();
    GameStart();//게임 시작
}
/////////////////////////////////////////////////////////////////////////////
// CTetris84View printing
BOOL CTetris84View::OnPreparePrinting(CPrintInfo* pInfo)
{
 // default preparation
 return DoPreparePrinting(pInfo);
}
void CTetris84View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
 // TODO: add extra initialization before printing
}
void CTetris84View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
 // TODO: add cleanup after printing
}
void CTetris84View::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/)
{
 // TODO: add customized printing code here
}
/////////////////////////////////////////////////////////////////////////////
// CTetris84View diagnostics
#ifdef _DEBUG
void CTetris84View::AssertValid() const
{
 CFormView::AssertValid();
}
void CTetris84View::Dump(CDumpContext& dc) const
{
 CFormView::Dump(dc);
}
CTetris84Doc* CTetris84View::GetDocument() // non-debug version is inline
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTetris84Doc)));
 return (CTetris84Doc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CTetris84View message handlers
/*void CTetris84View::OnButton1() 
{
 // TODO: Add your control notification handler code here
 MessageBox("메시지 Test.","보입니까");
 
}
*/
void CTetris84View::DrawOneBlock(int y,int x,int iSize, CClientDC *pDC, COLORREF crRGB)//CClientDC 현재 윈도우에 대한 클라이언트 영역의 dc를 얻어오는 기능 
{
 pDC->FillSolidRect((x)*iSize,(y)*iSize, iSize,iSize,crRGB);//m_iOneBlockSize=>iSize,
 pDC->Draw3dRect((x)*iSize,(y)*iSize, iSize,iSize,RGB(255,255,255),RGB(255,255,255));
}//차후 복잡도를 고려하여 블록 그리는 기능을 담당할 DrawOneBlock함수 생성
void CTetris84View::OnPaint() 
{ 
 CPaintDC dc(this); // device context for painting
 
 CClientDC pDC(this); // 현재 화면의 정보를 얻음
 CPen penLine; // 사용할 pen 의 셋팅
 CPen *OldPen; // 기존에 사용하던 설정으로 복구할 변수
 penLine.CreatePen(0,3,RGB(0,0,0));
 OldPen = pDC.SelectObject((&penLine));
 //pDC.FillSolidRect(m_iNowBlockX*m_iOneBlockSize,m_iNowBlockY*m_iOneBlockSize,m_iOneBlockSize,m_iOneBlockSize,RGB(150,150,150));
 for(int tempY=0;tempY<4;tempY++)
 {
  for(int tempX=0;tempX<4;tempX++)
  {
   if(0!=g_NowBlockInfo[m_iNowBlockShape][m_iNowBlockTurn][tempY][tempX])
   {
    DrawOneBlock(BOARD_Y_POS + m_iNowBlockY+tempY, BOARD_X_POS + m_iNowBlockX+tempX,m_iOneBlockSize,&pDC,RGB(50,0,250));
    //pDC.FillSolidRect((m_iNowBlockX+tempX)*m_iOneBlockSize,(m_iNowBlockY+tempY)*m_iOneBlockSize,m_iOneBlockSize,m_iOneBlockSize,RGB(250,250,250));
   }//Block 부분 그릴때( 흰색음영 으로 표시 )
   //BOARD_Y_POS 전체 Y좌표 위치,BOARD_X_POS 전체 X좌표 위치
   else
   {
    //DrawOneBlock(BOARD_Y_POS + m_iNowBlockY+tempY,BOARD_X_POS + m_iNowBlockX+tempX,m_iOneBlockSize,&pDC,RGB(200,200,200));//여기 수정해야할것 
    //pDC.FillSolidRect((m_iNowBlockX+tempX)*m_iOneBlockSize,(m_iNowBlockY+tempY)*m_iOneBlockSize,m_iOneBlockSize,m_iOneBlockSize,RGB(200,200,200));
   }//Block이 아닌 공백 부분 그릴때( 회색음영 으로 표시 )
  }
 }
 for(tempY=0;tempY<BOARD_Y_SIZE+1;tempY++)
 {
  for(int tempX=0;tempX<BOARD_X_SIZE+2;tempX++)
  {
   if(0!=g_BoardInfo[tempY][tempX])
   {
    DrawOneBlock((BOARD_Y_POS+tempY),BOARD_X_POS+tempX,m_iOneBlockSize,&pDC,RGB(0,0,0));
   }
  }
 }
//BOARD도 표시를 해줘야 하기때문에 기존의 1==을 0!=으로 수정함 
 //////////////////////////////////////////////////////////////////////////
 // 실제 출력될 내용 
 //pDC.TextOut(10,10,"화면에 글씨 출력");//좌 위치, RGB=>색상정보
 //pDC.Rectangle(100,100,150,150);
 //pDC.FillSolidRect(200,100,50,50,RGB(255,0,0));
 //pDC.FillSolidRect(280,100,50,50,RGB(0,255,0));
 /////////////////////////////////////////////////////////////////////////
 
 CString str;
 CString str1;
 CString str2;
 str.Format("%d",score);
 str1.Format("%d",level);
 str2.Format("%d",dItem);
 pDC.TextOut(400,20,"미리보기");
 pDC.TextOut(400,150,"점수 ");
 pDC.TextOut(400,200,str);
 pDC.TextOut(400,300,"레벨");
 pDC.TextOut(400,350,str1);
 pDC.TextOut(400,400,"싹쓸이 아이템");
 pDC.TextOut(400,450,str2);
 
 DrawNextBlock(&pDC);
 pDC.SelectObject(OldPen); // 기존의 상태로 복구
}
BOOL CTetris84View::PreTranslateMessage(MSG* pMsg) //키보드,메시지 처리 함수.
{
 // TODO: Add your specialized code here and/or call the base class
 if(WM_KEYDOWN ==pMsg->message)
 {
 
  if(VK_LEFT ==pMsg->wParam)//왼쪽키를 눌렀을시 
  {
   MoveLeft();//함수 호출 
   /*
   m_iNowBlockX--;//x좌표 값 1씩 감소 
   Invalidate();//Invalidate함수 호출->WM_PAINT메시지 발생->OnDraw()함수 호출
   */
   //MessageBox("VK_LEFT");//출력 
  }
  else if(VK_RIGHT ==pMsg->wParam)//오른쪽 키를 눌렀을 시
  {
   MoveRight();//함수 호출
   /*
   m_iNowBlockX++;//x좌표 값 1씩 증가
   Invalidate();
      */
   //MessageBox("VK_RIGHT");//출력
  }
  else if(VK_UP ==pMsg->wParam)//위쪽 키를 눌렀을 시 
  {
   MoveUp();//함수 호출
   /*
   m_iNowBlockY--;
   Invalidate();
   */
  
   //MessageBox("VK_UP");//출력
  }
  else if(VK_DOWN == pMsg->wParam)//아래쪽 키를 눌렀을 시
  {
   MoveDown();
            /* 
   m_iNowBlockY++;
   Invalidate();
   */
  
   //MessageBox("VK_DOWN");//출력
  }
  else if(VK_SPACE == pMsg->wParam)//Space Bar를 눌렀을 시
  {
   while(CanMove(m_iNowBlockTurn,m_iNowBlockY+1,m_iNowBlockX))//조건 설정
   MoveDown();//MoveDown함수 호출 
   OneLineRemove();//OneLineRemove함수 호출(삭제 기능)
  }
  else if(VK_SHIFT == pMsg->wParam)
  {
   //조건 설정
   if(dItem>0)
   {
    DeleteRemove();//OneLineRemove함수 호출(삭제 기능)
    dItem--;
   }
  }
    
 }
 return CFormView::PreTranslateMessage(pMsg);
 
}
void CTetris84View::OnTimer(UINT nIDEvent)// protected(다른 클래스 사용 없이 자신의 클래스에서 사용하여야 하기때문에)
// 초가 흘러감에 따라 바꿔줄수 있는 설정들
{
 if(CanMove(m_iNowBlockTurn,m_iNowBlockY+1,m_iNowBlockX))//Block이 밑으로 나가는것을 방지
 {
  m_iNowBlockY += 1;//일정시간마다 실행될 부분
 }
  //if(m_iNowBlockY>=20)
  else
  {
   OneLineRemove();//OneLineRemove함수 호출
  
   m_iNowBlockX=5;//벽돌을 가운데로 
   m_iNowBlockY=0;//벽돌이 바닥에 닿을때 가장위로 돌려줌
         m_iNowBlockShape=m_iNextBlockShape;
    //m_iNowBlockShape = (++m_iNowBlockShape)%7;//7가지 모양을 재현
   m_iNextBlockShape=rand()%7;
  }
  Invalidate();//Invalidate함수 호출->WM_TIMER메시지 발생->OnTimer()함수 호출
  CFormView::OnTimer(nIDEvent);
}
BOOL CTetris84View::MoveLeft()//public(모든 클래스에서 사용 가능)
{
  if(CanMove(m_iNowBlockTurn,m_iNowBlockY,m_iNowBlockX-1))
  {
     m_iNowBlockX -= 1;
     Invalidate();
  }
  return TRUE;//함수 리턴 
}
BOOL CTetris84View::MoveRight()//public
{
 if(CanMove(m_iNowBlockTurn,m_iNowBlockY,m_iNowBlockX+1))
 {
     m_iNowBlockX += 1;
     Invalidate();
 }
  return TRUE;//함수 리턴 
}
BOOL CTetris84View::MoveUp()//public (회전을 위한 함수)
{
  if(CanMove((m_iNowBlockTurn+1)%4,m_iNowBlockY,m_iNowBlockX))
  {
     m_iNowBlockTurn=(++m_iNowBlockTurn)%4; //4가지 배열중 하나를 택한 모양으로 나타냄,여기서 ++는 수를 하나씩 증가시키는 연산자로써 누락시킬 경우 변동이 되지를 않음.
     Invalidate();
  }
     return TRUE;//함수 리턴 
}
BOOL CTetris84View::MoveDown()//public
{
     m_iNowBlockY += 1;
     Invalidate();
  return TRUE;//함수 리턴 
}
BOOL CTetris84View::CanMove(int iDir,int iCheckY,int iCheckX)//블록이 나갈수 없는 범위 조건문  
{
 for(int iTempBlockY=0; iTempBlockY<4;iTempBlockY++)// Block을 기억해주는 iTempBlockX,iTempBlockY 변수 생성
 {
  for(int iTempBlockX=0;iTempBlockX<4;iTempBlockX++)
  {
   if(0!=g_BoardInfo[iCheckY+iTempBlockY][iCheckX+iTempBlockX] && 0!=g_NowBlockInfo[m_iNowBlockShape][iDir][iTempBlockY][iTempBlockX])
   {
    return FALSE;
   }
  }
 }
 return TRUE;
}
void CTetris84View::OneLineRemove()
{
 for(int iTempBlockY=0;iTempBlockY<4 && (m_iNowBlockY+iTempBlockY<BOARD_Y_SIZE+1);iTempBlockY++)// Block을 Board에 기억해주는 iTempBlockX,iTempBlockY 변수 생성
 {
  for(int iTempBlockX=0;iTempBlockX<4;iTempBlockX++)
  {
   if( 0 == g_BoardInfo[m_iNowBlockY+iTempBlockY][m_iNowBlockX+iTempBlockX])
   {
    if( 0!=g_NowBlockInfo[m_iNowBlockShape][m_iNowBlockTurn][iTempBlockY][iTempBlockX])
    {
     g_BoardInfo[m_iNowBlockY+iTempBlockY][m_iNowBlockX+iTempBlockX]=g_NowBlockInfo[m_iNowBlockShape][m_iNowBlockTurn][iTempBlockY][iTempBlockX];
    }
   }
  }
 }
 //한줄 없애기
 BOOL rOneLine=TRUE;
 for (iTempBlockY=0;iTempBlockY<4 && (m_iNowBlockY+iTempBlockY<BOARD_Y_SIZE);iTempBlockY++)
 {
   rOneLine=TRUE;
  {
   for(int iTempBlockX=0;iTempBlockX<BOARD_X_SIZE;iTempBlockX++)
   {
    if(0== g_BoardInfo[m_iNowBlockY+iTempBlockY][iTempBlockX])//빈칸이 있을 경우
    {
     rOneLine=FALSE;//실패 
     iTempBlockX=BOARD_X_SIZE;
    }
   }
   if(TRUE==rOneLine)//성공했을 경우
   {
    int iRemoveLine=m_iNowBlockY+iTempBlockY;//제거할 변수를 Y축으로 설정(y축을 삭제해야하기 때문에)
    DrawScore();
    DrawItem();
    for(int i=iRemoveLine;i>0;i--)
    {
     
     for(int j=1;j<BOARD_X_SIZE;j++)
     {
      g_BoardInfo[i][j]=g_BoardInfo[i-1][j];//y축 제거
      
     }
    }
    
   }
  }
  if(IsGameEnd())//게임이 끝났을 경우 
  {
   KillTimer(1);//timer종료 함수:timer를 중단시킨다.
   if(IDYES == MessageBox(" 한판 더?","게임이 끝났습니다. ",MB_YESNOCANCEL))
   {
    GameStart();//게임 재 시작
    level=1;
    score=0;
    dItem=0;
   }
  }
 }
}
BOOL CTetris84View::IsGameEnd()
{
 //X,Y축이 Block이 한줄당 적어도 하나의 빈공간이 생겨서 Block이 쌓여서 BOARD에 꽉 찰 때 
 for(int tempY= 0; tempY<2;tempY++)
 {
  for(int tempX=3; tempX<7; tempX++)
  {
   if(0 !=g_BoardInfo[tempY][tempX])
   {
    return TRUE;
   }
  }
 }
 return FALSE;
}
void CTetris84View::GameStart()
{
 SetTimer(1,1000,NULL);//1번 타이머를 1000mS(1초마다 동작),(타이머 초기화)
 srand((unsigned)time(NULL));
 m_iNowBlockShape = rand()%7;
 m_iNextBlockShape = rand()%7;
 m_iNowBlockTurn=0;
 m_iNowBlockX=5;
 m_iNowBlockY=0;
 m_iOneBlockSize=25;
 //Block의 시작위치,크기 초기화
 for(int tempY=0;tempY<BOARD_Y_SIZE+1;tempY++)
 {
  for(int tempX=0; tempX<BOARD_X_SIZE+2;tempX++)
  {
   g_BoardInfo[tempY][tempX]=0;
  }
 }
 //BOARD범위를 기억
 int i;
 for(i=0;i<BOARD_Y_SIZE;i++)
 {
  g_BoardInfo[i][0]=50;
 }//보드의 좌측벽 
 for(i=0;i<BOARD_Y_SIZE;i++)
 {
  g_BoardInfo[i][BOARD_X_SIZE+1]=50;
 }//보드의 우측벽
 for(i=0;i<BOARD_X_SIZE+2;i++)
 {
  g_BoardInfo[BOARD_Y_SIZE][i]=50;
 }//보드의 하단벽 
}
void CTetris84View::DrawNextBlock(CClientDC *pDC)//다음에 나올 Block을 그려줌 
{
 for(int tempY=0;tempY<4;tempY++)
 {
  for(int tempX=0;tempX<4;tempX++)
  {
   if(0!=g_NowBlockInfo[m_iNextBlockShape][0][tempY][tempX])
   {
    DrawOneBlock((BOARD_Y_POS+tempY),BOARD_X_POS+BOARD_X_SIZE+3+tempX,m_iOneBlockSize,pDC,RGB(50,200,200));
   }
  }
 }
}
int CTetris84View::score=0;
int CTetris84View::level=1;
int CTetris84View::dItem=0;
void CTetris84View::DrawScore()
{
 score++;
 if(score%2==0)
 {
  level++;
  timer-=200;
  SetTimer(1,timer,NULL);
 }  
/* if(level%5==0)
 {
*/
}
//자료구조,알고리즘
void CTetris84View::DrawItem()
{
 if(level%3==0)
 {
  dItem++;
 }
}
 
void CTetris84View::DeleteRemove()
{
 //g_BoardInfo[BOARD_Y_SIZE+1][BOARD_X_SIZE+2];
for(int tempY=0;tempY<BOARD_Y_SIZE+1;tempY++)
 {
  for(int tempX=0; tempX<BOARD_X_SIZE+2;tempX++)
  {
   g_BoardInfo[tempY][tempX]=0;
  }
 }
 //BOARD범위를 기억
 int i;
 for(i=0;i<BOARD_Y_SIZE;i++)
 {
  g_BoardInfo[i][0]=50;
 }//보드의 좌측벽 
 for(i=0;i<BOARD_Y_SIZE;i++)
 {
  g_BoardInfo[i][BOARD_X_SIZE+1]=50;
 }//보드의 우측벽
 for(i=0;i<BOARD_X_SIZE+2;i++)
 {
  g_BoardInfo[BOARD_Y_SIZE][i]=50;
 }//보드의 하단벽  
}

 
	
		 


 
    
 
    
 
     
전제 파일을 올려 주세요.~~
실행하면서 디버깅해야 찾을수 있고, 소스를 눈으로면 봐서 알수가 없습니다..
여기에 소스 올리기 좀 곤란하시면, kkjk1@네 이 버 로 보내 주세요.~~