반응형
이번 회차에서는 오목게임의 근간이 되는 오목클래스를 디자인하고 우선 오목판을 그려봅니다.
오목클래스는 개발이 완료될 때까지 단계적으로 구현해야 할 중요한 영역입니다. 객체지향의 핵심이 되는 클래스/객체 개념은 별도로 꼭 학습해 보시길 권장합니다.
오목클래스(COmok) 정의
오목클래스는 오목게임의 중요한 로직을 담고 있는 핵심클래스가 됩니다. 단계적으로 진행하면서 계속 개발하고 보완해 나갈 예정입니다. 오목클래스는 COmok.cs라는 별도의 파일에 작성합니다.
namespace Omok
{
internal class COmok
{
...
}
}
멤버변수
오목의 여러 속성들을 멤버변수로 정의합니다.
- 주요 상수 정의
- 게임환경변수 정의
- 오목판정보 배열 정의
Graphics g;
int boardMargin = 60;
int boardSize = 19;
int boardInterval = 50;
int stoneSize = 48;
int dotSize = 8;
bool gameOver = false;
char playerType = 'C';
char firstPlayer = 'H';
//착수정보List
List<CPoint> mainList = new List<CPoint>();
//오목판 배열(15*15 or 19*19)
char[,] mainBoard;
readonly string[][] omokPattern = new string[2][]
{
new string[] { "EBBBBBE", "EBBBBBW", "EBBBBBX", "WBBBBBE", "WBBBBBW", "WBBBBBX", "XBBBBBE", "XBBBBBW", "XBBBBBX" },
new string[] { "WWWWW" }
};
생성자
생성자는 객체가 생성될 때 최초에 한번 실행되는 함수로써 주로 초기화를 진행합니다.
- 그래픽 객체 생성
- 오목판 사이즈 초기화
- 상대선수 초기화
- 흑 선수 초기화
- 사이즈에 따른 오목판 격자간격 값 초기화
- 오목판 배열정보 생성
public COmok(Graphics graphics, int boardSize, char playerType, char firstPlayer)
{
this.g = graphics;
this.boardSize = boardSize;
this.playerType = playerType;
this.firstPlayer = firstPlayer;
mainBoard = new char[this.boardSize + 1, this.boardSize + 1];
this.boardInterval = boardSize == 15 ? 50 : 39;
this.stoneSize = boardSize == 15 ? 48 : 37;
}
멤버함수(메서드)
처리에 필요한 함수들을 정의합니다. 오목객체가 생성되면 멤버함수들을 이용해서 오목과 관련된 대부분의 처리를 수행하게 됩니다.
- 오목판 그리기 : 오목판 영역을 초기화하고 격자와 점을 그리는 함수입니다.
public void DrawBoard(Graphics g)
{
Pen pen = new Pen(Color.Black);
Point point;
char[] alphabet = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S' };
//오목판 격자 표시
for (int i = 0; i < boardSize - 1; i++)
{
for (int j = 0; j < boardSize - 1; j++)
{
Rectangle rec = new Rectangle((i * boardInterval) + boardMargin, (j * boardInterval) + boardMargin, boardInterval, boardInterval);
g.DrawRectangle(pen, rec);
}
}
//점 표시
if (boardSize == 15)
{
DrawStone(g, 4, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 12, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 4, 12, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 8, 8, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 12, 12, 'B', 0, false, (int)DrawType.BoardPoint);
}
else if (boardSize == 19)
{
DrawStone(g, 4, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 10, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 16, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 4, 10, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 10, 10, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 16, 10, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 4, 16, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 10, 16, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 16, 16, 'B', 0, false, (int)DrawType.BoardPoint);
}
//위치번호, 알파벳 표시
for (int i = 1; i <= boardSize; i++)
{
g.DrawString(i.ToString(), new Font("Arial", 10), new SolidBrush(Color.Black), 35, (boardInterval * i) + (boardSize == 15 ? 3 : 14));
g.DrawString(alphabet[i - 1].ToString(), new Font("Arial", 10), new SolidBrush(Color.Black), (boardInterval * i) + (boardSize == 15 ? 5 : 15), 30);
}
}
- 오목판 점 그리기 : 오목판의 주어진 위치에 점을 그려주는 함수입니다.
private void DrawStone(Graphics g, int x, int y)
{
Point point = GetScreenPosition(new Point(x, y));
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)));
}
//오목판 위치정보를 화면 위치정보로 변경
private Point GetScreenPosition(Point point)
{
return new Point((point.X - 1) * boardInterval + boardMargin - (stoneSize / 2), (point.Y - 1) * boardInterval + boardMargin - (stoneSize / 2));
}
오목클래스(COmok.cs) 전체 코드
현재까지 정의한 오목클래스 전체 소스코드입니다. 오목클래스는 별도의 COmok.cs파일로 생성합니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Omok
{
internal class COmok
{
Graphics g;
int boardMargin = 60;
int boardSize = 19;
int boardInterval = 50;
int stoneSize = 48;
int dotSize = 8;
bool gameOver = false;
char playerType = 'C';
char firstPlayer = 'H';
//착수정보List
List<CPoint> mainList = new List<CPoint>();
//오목판 배열(15*15 or 19*19)
char[,] mainBoard;
readonly string[][] omokPattern = new string[2][]
{
new string[] { "EBBBBBE", "EBBBBBW", "EBBBBBX", "WBBBBBE", "WBBBBBW", "WBBBBBX", "XBBBBBE", "XBBBBBW", "XBBBBBX" },
new string[] { "WWWWW" }
};
public COmok(Graphics graphics, int boardSize, char playerType, char firstPlayer)
{
this.g = graphics;
this.boardSize = boardSize;
this.playerType = playerType;
this.firstPlayer = firstPlayer;
mainBoard = new char[this.boardSize + 1, this.boardSize + 1];
this.boardInterval = boardSize == 15 ? 50 : 39;
this.stoneSize = boardSize == 15 ? 48 : 37;
}
public void DrawBoard(Graphics g)
{
Pen pen = new Pen(Color.Black);
Point point;
char[] alphabet = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S' };
//오목판 격자 표시
for (int i = 0; i < boardSize - 1; i++)
{
for (int j = 0; j < boardSize - 1; j++)
{
Rectangle rec = new Rectangle((i * boardInterval) + boardMargin, (j * boardInterval) + boardMargin, boardInterval, boardInterval);
g.DrawRectangle(pen, rec);
}
}
//점 표시
if (boardSize == 15)
{
DrawStone(g, 4, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 12, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 4, 12, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 8, 8, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 12, 12, 'B', 0, false, (int)DrawType.BoardPoint);
}
else if (boardSize == 19)
{
DrawStone(g, 4, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 10, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 16, 4, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 4, 10, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 10, 10, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 16, 10, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 4, 16, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 10, 16, 'B', 0, false, (int)DrawType.BoardPoint);
DrawStone(g, 16, 16, 'B', 0, false, (int)DrawType.BoardPoint);
}
//위치번호, 알파벳 표시
for (int i = 1; i <= boardSize; i++)
{
g.DrawString(i.ToString(), new Font("Arial", 10), new SolidBrush(Color.Black), 35, (boardInterval * i) + (boardSize == 15 ? 3 : 14));
g.DrawString(alphabet[i - 1].ToString(), new Font("Arial", 10), new SolidBrush(Color.Black), (boardInterval * i) + (boardSize == 15 ? 5 : 15), 30);
}
}
private void DrawStone(Graphics g, int x, int y)
{
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)));
}
private Point GetScreenPosition(Point point)
{
return new Point((point.X - 1) * boardInterval + boardMargin - (stoneSize / 2), (point.Y - 1) * boardInterval + boardMargin - (stoneSize / 2));
}
}
}
반응형
오목판 그리기
현재까지 정의한 오목클래스와 오목판 그리기 멤버함수를 이용해서 오목판을 그리는 코드를 작성합니다.
메인 프로그램 수정
- Form1.cs 파일에 오목객체 생성하는 코드와 오목판 그리는 코드를 추가합니다.
- 오목객체 생성 : omok = new COmok(g, boardSize, playType, firstPlayer);
- 오목판 그리는 멤버함수 호출 : omok.DrawBoard(e.Graphics);
Form1 로드 시에 오목객체를 생성하고 Refresh() 이벤트가 발생할 때마다 오목판이 다시 그려지도록 panel_Paint() 함수에 추가해 준다.
private void Form1_Load(object sender, EventArgs e)
{
g = CreateGraphics();
//게임설정 초기화
radioButtonSize15.Checked = true;
radioButtonEnemyCom.Checked = true;
radioButtonFirstHuman.Checked = true;
if (radioButtonSize15.Checked) boardSize = 15;
if (radioButtonSize19.Checked) boardSize = 19;
if (radioButtonEnemyHuman.Checked) playType = 'H';
if (radioButtonEnemyCom.Checked) playType = 'C';
if (radioButtonFirstHuman.Checked) firstPlayer = 'H';
if (radioButtonFirstCom.Checked) firstPlayer = 'C';
//COmok 객체 생성
omok = new COmok(g, boardSize, playType, firstPlayer);
}
private void panel_Paint(object sender, PaintEventArgs e)
{
omok.DrawBoard(e.Graphics);
}
실행결과 화면
지금까지의 코드를 실행하면 아래와 같이 오목판이 그려지게 됩니다.
현재는 15*15 사이즈로 설정되었기 때문에 아래와 같은 형태로 그려집니다.
앞으로 이 오목판 위에 착수시마다 오목돌을 그려나가게 됩니다.
반응형
'개발노트 > 오목게임_C#' 카테고리의 다른 글
C# 오목 게임 개발 #7 (0) | 2023.01.30 |
---|---|
C# 오목 게임 개발 #6 (0) | 2023.01.30 |
C# 오목 게임 개발 #4 (0) | 2023.01.30 |
C# 오목 게임 개발 #3 (0) | 2023.01.30 |
C# 오목 게임 개발 #2 (0) | 2023.01.30 |
댓글