간단하진 않겠지만, 체스 게임을 한 번 만들어보기로 했습니다.
자꾸 말투가 높임말에서 왔다갔다 한 것 같다면 기분 탓입니다. (분명 기분 탓일 겁니다!)
글을 시작하기 앞서,
이 글은 체스 AI, 혹은 네트워크에 대해 다루지 않을 것입니다.
그냥 단순히 혼자서 흑백 다 움직이는 그런 프로그램을 짤겁니다.
뭐, 본론으로 돌아와서... 판 만들고 체스말 놓는데 2시간이 걸렸다면 믿으시겠나요 ㅎ..
우선 우리가 흔히 아는 8x8의 격자를 만들어봅시다.
xaml로 처리할 수도 있지만, 64개를 쌩으로 만들기 싫었기 때문에 스크립트로 작성하고자 했습니다.
private void SetBoard() {
for(int i = 0; i < 8; i++) {
RowDefinition row = new RowDefinition();
ColumnDefinition column = new ColumnDefinition();
row.Height = new GridLength(1, GridUnitType.Star);
column.Width = new GridLength(1, GridUnitType.Star);
Board.ColumnDefinitions.Add(column);
Board.RowDefinitions.Add(row);
}
SolidColorBrush oddBrush = new SolidColorBrush(Color.FromArgb(255, 162, 59, 59));
SolidColorBrush evenBrush = new SolidColorBrush(Color.FromArgb(255, 250, 232, 200));
for(int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
Canvas canvas = new Canvas { Background = (i + j) % 2 == 0 ? evenBrush : oddBrush };
Board.Children.Add(canvas);
Grid.SetColumn(canvas, j);
Grid.SetRow(canvas, i);
}
}
}
스크립트는 다음과 같습니다. 원래는 Rectangle로 하려 했는데, 이 위에 기물까지 올릴 생각이여서 캔버스로 바꿨습니다.
Definition 설정을 안 해주면 캔버스 하나가 그리드 전체를 잡아먹습니다. 반드시 설정해줍시다.
(Board는 xaml코드에 만들어놓은 그리드입니다)
GridUnitType은 Star로 설정하면 xaml에서 쓰던 "*"가 되며, Auto로 설정하면 "Auto"가 됩니다(이때, 숫자는 0으로 하는 듯합니다). 만일 타입을 넘기지 않을 경우, 그냥 픽셀 값으로 알아먹습니다.
2차전: 기물 놓기
for(int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
Canvas canvas = new Canvas { Background = (i + j) % 2 == 0 ? evenBrush : oddBrush };
/* 새로 작성한 부분 */
if(i == 0 || i == 7) {
Image image = new Image {
Height = 50,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
switch(j) {
case 0:
string img_uri1 = i == 0 ? "ms-appx:///Piece/white_rook.png" : "ms-appx:///Piece/black_rook.png";
image.Source = new BitmapImage(new Uri(img_uri1));
canvas.Children.Add(image);
break;
case 1:
string img_uri2 = i == 0 ? "ms-appx:///Piece/white_knight.png" : "ms-appx:///Piece/black_knight.png";
image.Source = new BitmapImage(new Uri(img_uri2));
canvas.Children.Add(image);
break;
case 2:
string img_uri3 = i == 0 ? "ms-appx:///Piece/white_bishop.png" : "ms-appx:///Piece/black_bishop.png";
image.Source = new BitmapImage(new Uri(img_uri3));
canvas.Children.Add(image);
break;
case 3:
string img_uri4 = i == 0 ? "ms-appx:///Piece/white_queen.png" : "ms-appx:///Piece/black_king.png";
image.Source = new BitmapImage(new Uri(img_uri4));
canvas.Children.Add(image);
break;
case 4:
string img_uri5 = i == 0 ? "ms-appx:///Piece/white_king.png" : "ms-appx:///Piece/black_queen.png";
image.Source = new BitmapImage(new Uri(img_uri5));
canvas.Children.Add(image);
break;
case 5:
img_uri3 = i == 0 ? "ms-appx:///Piece/white_bishop.png" : "ms-appx:///Piece/black_bishop.png";
image.Source = new BitmapImage(new Uri(img_uri3));
canvas.Children.Add(image);
break;
case 6:
img_uri2 = i == 0 ? "ms-appx:///Piece/white_knight.png" : "ms-appx:///Piece/black_knight.png";
image.Source = new BitmapImage(new Uri(img_uri2));
canvas.Children.Add(image);
break;
case 7:
img_uri1 = i == 0 ? "ms-appx:///Piece/white_rook.png" : "ms-appx:///Piece/black_rook.png";
image.Source = new BitmapImage(new Uri(img_uri1));
canvas.Children.Add(image);
break;
}
}
else if(i == 1 || i == 6) {
string img_uri = i == 2 ? "ms-appx:///Piece/white_pawn.png" : "ms-appx:///Piece/black_pawn.png";
canvas.Children.Add(new Image { Source = new BitmapImage(new Uri(img_uri)),
Height = 50,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center});
}
/* 새로 작성한 부분 */
Board.Children.Add(canvas);
Grid.SetColumn(canvas, j);
Grid.SetRow(canvas, i);
}
}
격자는 비교적 순조롭게 만들었으나, 기물 놓기가 생각보다 오래 걸렸습니다. 아래는 오래 걸린 이유이자 해결방법입니다.
1. xaml과 달리 uri를 코드로 작성해서 쓰려면 "ms-apps:///"가 항상 경로 앞에 작성되어야 한다.
2. 사진을 불러오면 빌드 작업을 "내용"으로 바꿔야 한다.
이걸 안 해줘서 당연히 안 나타난 것 뿐이었는데 왜 안되나 이것저것 뒤져보고 코드 고쳐보고... 허허..
그래도 잘 나오니까! (근데 분명히 센터로 정렬을 해줬는데 중앙에 딱 배치되지는 않습니다.)
판 만드는 것까지 끝!
.
.
움직이는 거 구현하려면 얼마나 걸릴지 상상이 안 갑니다....
'C# > WinUI3' 카테고리의 다른 글
WinUI3에서 C++ 사용하기 (WinRT 아님) (0) | 2023.07.20 |
---|---|
[WinUI3] 체스 게임 만들기(2) : 말 선택하기 (0) | 2023.02.10 |
[WinUI3] 창 테두리 없애기, Title, Icon... 그리고 TitleBar. (2) | 2023.02.05 |
[WinUI3] NoResize, 생성 시 창의 크기 (0) | 2023.02.05 |
[WinUI3] FileOpenPicker 사용하여 이미지 불러오기 (0) | 2023.02.04 |