이번 회차에서는 오목판 위에 실제 오목돌을 그리는 클램스 멤버함수 및 호출 부분을 구현해 보겠습니다.
오목판의 특정 위치를 마우스로 좌클릭하면 흑돌부터 순서대로 그려지도록 합니다.
COmok 클래스 멤버함수 추가 (COmok.cs)
오목돌을 그리기 위한 COmok 클래스의 멤버함수를 구현합니다.
오목돌 그리는 방법
먼저 오목돌을 그리는 방법에 대해 정리한 후에 실제 코드를 작성합니다.
오목돌은 마우스 클릭 이벤트 발생시점에 해당 위치에 직접 그려주는 방법도 있지만, 여기에서는 아래와 같이 오목돌 착수정보를 관리하는 배열에 추가(push) 한 후에 착수정보배열을 기준으로 전체 오목돌을 다시 그려주는 방법으로 구현해 보겠습니다.
오목위치 구하기
panel상의 마우스 클릭 위치 좌표를 오목판 사이즈(15*15 or 19*19)에 맞는 위치로 변환하는 멤버함수입니다.
오목판 교차점 부근의 위치를 계산하여 오목판 사이즈에 따른 위치로 변환합니다.
//화면 위치를 오목판(15*15 or 19*19) 위치로 변환하기
public Point GetBoardPosition(int screenX, int screenY)
{
return new Point((int)((screenX - boardMargin + boardInterval / 2) / boardInterval) + 1, (int)((screenY - boardMargin + boardInterval / 2) / boardInterval) + 1);
}
화면위치 구하기
화면 상에 오목돌을 그리기위해 오목판의 위치정보를 화면 상의 위치정보로 변환하는 멤버함수입니다.
오목판의 각 교차점에 오목돌이 놓여질 위치를 계산하여 변환합니다.
//오목판(15*15 or 19*19) 위치를 화면 위치로 변환하기
private Point GetScreenPosition(Point point)
{
return new Point((point.X - 1) * boardInterval + boardMargin - (stoneSize / 2), (point.Y - 1) * boardInterval + boardMargin - (stoneSize / 2));
}
착수정보 저장
마우스 클릭한 위치를 오목판의 위치로 변환하고 오목돌의 색깔을 구해서 착수정보List(mainList)의 마지막 요소에 추가하는 멤버함수입니다. 매 착수 시마다 추가되며 착수정보List에 추가될 때마다 2차원 오목판 배열(mainBoard)도 새롭게 갱신해 줍니다.
public void PutStone(int x, int y)
{
char nextColor = 'B';
//착수돌 색깔 구하기
if (mainList.Count > 0)
{
nextColor = mainList[mainList.Count - 1].Color == 'B' ? 'W' : 'B';
}
//착수정보List(mainList)에 착수정보 추가
mainList.Add(new CPoint(GetBoardPosition(x, y).X, GetBoardPosition(x, y).Y, nextColor));
//오목판 배열(mainBoard) 초기화 후 갱신
for (int i = 0; i < boardSize + 1; i++)
{
for (int j = 0; j < boardSize + 1; j++)
{
if (i == 0 || j == 0)
mainBoard[i, j] = 'X';
else
mainBoard[i, j] = 'E';
}
}
//착수정보List 기준으로 오목판 배열(mainBoard) 갱신
foreach (CPoint p in mainList)
{
mainBoard[p.X, p.Y] = p.Color;
}
}
오목돌 그리기
하나의 착수정보를 받아서 해당 위치에 해당 색상의 오목돌을 그리는 멤버함수입니다.
오목판의 점을 그리는 형태가 유사하므로 같은 함수를 사용하도록 아래와 같이 코드를 추가합니다.
...
//그리는 유형을 구분하기 위한 enum 변수 선언
enum DrawType
{
OmokStone = 1, //오목돌(흑/백)
BoardPoint = 2 //오목판 점 표시
};
...
//하나의 오목돌을 그리는 멤버함수
//type은 오목돌과 오목판의 점을 구분하여 그리기 위한 enum 유형 파라미터
private void DrawStone(Graphics g, int x, int y, char color, int type)
{
Point point = GetScreenPosition(new Point(x, y));
if (type == (int)DrawType.OmokStone)
{
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
if (color == 'B')
{
g.FillEllipse(Brushes.Black, new Rectangle(point, new Size(stoneSize, stoneSize)));
g.DrawEllipse(Pens.Black, new Rectangle(point, new Size(stoneSize, stoneSize)));
}
else
{
g.FillEllipse(Brushes.White, new Rectangle(point, new Size(stoneSize, stoneSize)));
g.DrawEllipse(Pens.DarkGray, new Rectangle(point, new Size(stoneSize, stoneSize)));
}
}
else if (type == (int)DrawType.BoardPoint)
{
point.X = (x - 1) * boardInterval + boardMargin - (dotSize / 2);
point.Y = (y - 1) * boardInterval + boardMargin - (dotSize / 2);
g.FillEllipse(Brushes.Black, new Rectangle(point, new Size(dotSize, dotSize)));
g.DrawEllipse(Pens.Black, new Rectangle(point, new Size(dotSize, dotSize)));
}
}
//착수정보List에 있는 전체 오목돌을 그리는 멤버함수
public void DrawStoneAll(Graphics g)
{
foreach (var item in mainList.Select((value, index) => (value, index)))
{
DrawStone(g, item.value.X, item.value.Y, item.value.Color, (int)DrawType.OmokStone);
}
}
오목돌 그리기 구현 (Form1.cs)
위에서 작성한 COmok 클래스의 멤버함수를 이용하여 마우스 클릭 시 실제 오목돌을 그리는 코드를 작성합니다.
오목판 마우스 클릭 함수 작성
오목판 클릭시 오목돌이 그려지게 하기 위한 panel 마우스클릭 이벤트 함수를 작성합니다.
마우스 클릭시 착수배열List에 추가하는 omok.PutStone() 클래스함수를 실행하고 Refresh()함수를 호출하면 panel_Paint()함수가 자동 호출되면서 오목판 및 오목돌이 그려지게 됩니다.
//오목판 마우스 클릭이벤트 함수
private void panel_MouseDown(object sender, MouseEventArgs e)
{
//착수정보 생성(추가) 및 착수점 분석
omok.PutStone(e.Location.X, e.Location.Y);
//화면 Refresh
Refresh();
}
//panel 다시 그리기 함수
private void panel_Paint(object sender, PaintEventArgs e)
{
omok.DrawBoard(e.Graphics);
omok.DrawStoneAll(e.Graphics);
}
실행결과 확인
지금까지 작성한 코드를 실행하여 아래와 같이 정상적으로 오목돌이 그려지는지 확인합니다.
'개발노트 > 오목게임_C#' 카테고리의 다른 글
C# 오목 게임 개발 #8 (0) | 2023.01.30 |
---|---|
C# 오목 게임 개발 #7 (0) | 2023.01.30 |
C# 오목 게임 개발 #5 (0) | 2023.01.30 |
C# 오목 게임 개발 #4 (0) | 2023.01.30 |
C# 오목 게임 개발 #3 (0) | 2023.01.30 |
댓글