이번 회차에는 정확한 착수여부를 체크하는 코드와 새게임, 무르기 처리 기능을 구현해 보겠습니다.
추가적으로, 착수 시에 사운드 재생하는 코드를 같이 작성해 보겠습니다.
COmok 클래스 멤버함수 추가 (COmok.cs)
정확한 착수인지를 체크하기 위한 COmok 클래스의 멤버함수를 구현합니다.
착수점에 이미 돌이 있는지 여부 체크 함수
착수점(마우스 클릭점)에 기존에 이미 돌이 있는지를 확인하는 멤버함수입니다.
착수정보List(mainList)에서 착수점(x,y)으로 검색하여 존재하는지 여부로 판단합니다.
public bool IsOccupied(int x, int y)
{
foreach (var item in mainList)
{
if (item.X == x && item.Y == y)
return true;
}
return false;
}
착수정보List(mainList)를 검색하여 착수점과 동일한 위치가 있으면 true/false를 return하여 존재여부를 판단하는 코드입니다.
무르기 처리 함수
무르기 버튼을 클릭하면 마지막에 착수한 수를 제거하는 멤버함수입니다.
착수정보List(mainList)에서 마지막 착수정보를 제거하고 다시 그리기를 하면 무르기 처리가 됩니다.
기본적으로 마지막 수를 제거하고 다시 그리기를 하면 되지만, 제거한 후의 마지막 수에 대해 추후 착수정보를 분석하는 로직을 정상 착수 시점(PutStone 함수)이 아닌 무르기 시점에도 중복 코딩해야 상황이 발생하기 때문에 제거 후의 마지막 수를 착수함수(PutStone)를 통해 처리하게 했습니다.
public void UnDo()
{
Point point;
//첫 수만 둔 상태이면 해당 첫 수만 제거
if (mainList.Count == 1)
{
mainList.RemoveAt(mainList.Count - 1);
//mainBoard배열 E(공백)로 초기화후 재 세팅
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';
}
}
}
}
//두 수 이상을 둔 상태이면, 마지막 수를 제거한 후 그 다음 마지막 수의 위치를 보관후 삭제한 다음에 다시 착수하는 형태로 진행함
//이렇게 하는 이유는 추후 착수시 착수정보 등을 추출하는 로직부분을 중복해서 코딩하지 않도록 하기 위함
else if (mainList.Count > 1)
{
mainList.RemoveAt(mainList.Count - 1);
point = new Point(mainList[mainList.Count - 1].X, mainList[mainList.Count - 1].Y);
mainList.RemoveAt(mainList.Count - 1);
this.PutStone(this.GetScreenPosition(point).X, this.GetScreenPosition(point).Y);
}
}
Form1.cs 로직 구현
위에서 작성한 COmok 클래스의 멤버함수를 이용하여 실제 동작하는 코드를 작성합니다.
클릭위치가 오목판 내부인지 체크하여 return
마우스 클릭위치가 오목판을 벗어난 경우는 정상적인 착수가 아니므로 무시하도록 하는 코드를 작성합니다.
private void panel_MouseDown(object sender, MouseEventArgs e)
{
//오목판 위치 구하기
Point boardPoint = omok.GetBoardPosition(e.Location.X, e.Location.Y);
//오목판(15*15 or 19*19)을 벗어나서 체크된 경우 return
if (boardPoint.X < 1 || boardPoint.X > omok.GetBoardSize() || boardPoint.Y < 1 || boardPoint.Y > omok.GetBoardSize())
return;
//착수정보 생성(추가) 및 착수점 분석
omok.PutStone(e.Location.X, e.Location.Y);
//화면 Refresh
Refresh();
}
오목판 사이즈(15*15 or 19*19) 선택에 따라 자동으로 체크되도록 omok.GetBoardSize() 멤버함수를 통해 체크합니다.
마우스 클릭 위치에 이미 착수한 돌이 있으면 return
기 착수된 점에 마우스를 클릭한 경우 정상적인 착수가 아니므로 기 착수여부를 체크하여 return하는 코드를 작성합니다.
기 착수여부는 위에서 작성한 COmok클래스의 멤버함수인 isOccupied() 함수를 이용합니다.
private void panel_MouseDown(object sender, MouseEventArgs e)
{
//오목판 위치 구하기
Point boardPoint = omok.GetBoardPosition(e.Location.X, e.Location.Y);
//오목판(15*15 or 19*19)을 벗어나서 체크된 경우 return
if (boardPoint.X < 1 || boardPoint.X > omok.GetBoardSize() || boardPoint.Y < 1 || boardPoint.Y > omok.GetBoardSize())
return;
//이미 착수된 점을 클릭한 경우 return
if (omok.IsOccupied(boardPoint.X, boardPoint.Y)) return;
//착수정보 생성(추가) 및 착수점 분석
omok.PutStone(e.Location.X, e.Location.Y);
//화면 Refresh
Refresh();
}
새게임 처리
오목판 사이즈, 상대선수 및 흑 선수를 선택하고 시작 버튼을 클릭하여 새로운 게임을 시작하도록 하는 코드를 작성합니다. 진행 중인 게임을 초기화하고 새로 선택한 게임설정정보로 새로운 게임을 시작하는 기능입니다.
게임이 진행 중인 경우는 확인창을 띄워 재시작여부를 확인하도록 합니다.
private void startButton_Click(object sender, EventArgs e)
{
bool restartFlag = false;
if (omok.GetMainList().Count > 0)
{
DialogResult res = MessageBox.Show("게임 진행 중입니다. 다시 시작하겠습니까?", "확인", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
if (res == DialogResult.OK)
{
restartFlag = true;
}
if (res == DialogResult.Cancel)
{
restartFlag = false;
}
}
else
{
restartFlag = true;
}
if (restartFlag)
{
omok = new COmok(g, boardSize, playType, firstPlayer);
Refresh();
}
}
무르기 처리
무르기 버튼을 클릭하면 위에서 작성한 Omok클래스의 무르기 처리 멤버함수를 호출한 후에 오목판을 다시 그려주는 코드를 작성합니다. Undo()처리를 한 후에 Refresh()함수를 호출하여 panel_Paint()함수를 통해 오목판 및 오목돌이 다시 그려지게 처리합니다.
private void undoButton_Click(object sender, EventArgs e)
{
omok.UnDo();
Refresh();
}
실행결과 확인
오목판 사이즈를 19*19로 선택하고 (재)시작 버튼을 클릭하여 실행한 결과입니다.
'개발노트 > 오목게임_C#' 카테고리의 다른 글
C# 오목 게임 개발 #9 (0) | 2023.01.30 |
---|---|
C# 오목 게임 개발 #8 (0) | 2023.01.30 |
C# 오목 게임 개발 #6 (0) | 2023.01.30 |
C# 오목 게임 개발 #5 (0) | 2023.01.30 |
C# 오목 게임 개발 #4 (0) | 2023.01.30 |
댓글