C#

046_Matching Game(그림 맞추기 게임)_C#

iwannabebackendexpert 2022. 6. 9. 04:10

그림맞추기 게임을 만들어보자!

 

알고리즘

1. 16개의 버튼을 만들어서, Board에 넣는다.

2. 랜덤하게 각 버튼에 숫자(0~7)을 배당한다.

3. 이 숫자를 Button.Tag에 저장한다.

4. 뒤집한 그림으로 표시한다.

	int[] rnd = new int[16];   // TagSet()에서 사용할 배열
        DispatcherTimer myTimer = new DispatcherTimer();

총 16개의 그림을 비교할 것이니 배열크기를 16으로 정한다.

그림 하나를 선택 후, 다음 그림이 열릴때 너무 빨리 닫히므로 두번째 그림을 확인할 수 없게된다. 그래서 WPF의 시간을 사용하는 클래스인 DispatcherTime 객체를 선언한다.

public MainWindow()
        {
            InitializeComponent();
            BoardSet();
            myTimer.Interval = new TimeSpan(0, 0, 0, 0, 750);
            myTimer.Tick += MyTimer_Tick;
        }
private void MyTimer_Tick(object sender, EventArgs e)
        {
            myTimer.Stop();
            first.Content = MakeImage("../../images/check.png");
            second.Content = MakeImage("../../images/check.png");
            first = null;
            second = null;
        }

타이머 설정 및 이미지 불러오기. 시간은 750ms  = 0.75초

private void BoardSet()
        {
            for (int i = 0; i < 16; i++)
            {
                Button btn = new Button();
                btn.Background = Brushes.White;
                btn.Margin = new Thickness(10);

                btn.Tag = TagSet();     // 랜덤하고 각 숫자가 2개씩
                btn.Content = MakeImage("../../images/check.png");  // 그림으로 대체될 것임

                // 버튼의 클릭 이벤트 설정
                btn.Click += Btn_Click;

                board.Children.Add(btn);
            }
        }

16개의 배열 처럼 16칸의 버튼을 만들어준다.

TagSet() 함수 사용 ( 후술 ) 랜덤하고 각각의 숫자 2개씩 지정하기 위함.

private void Btn_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;

            string[] icon = {"딸기", "레몬", "모과", "배",
            "사과", "수박", "파인애플", "포도"};
            string fruitName = icon[(int)btn.Tag];

            if (first == null)  // 누른 버튼이 첫번째 버튼이라면
            {
                first = btn;
                btn.Content = MakeImage("../../images/" + fruitName + ".png");
                return;
            }
            else if (second == null) // 지금 누른 버튼이 두번째 버튼이라면
            {
                second = btn;
                btn.Content = MakeImage("../../images/" + fruitName + ".png");
            }
            else
            {
                return;
            }

            // 비교하기
            if ((int)first.Tag == (int)second.Tag)  // 같다
            {
                first = null;
                second = null;
                matched += 2;  // 매칭된 버튼의 개수
                if (matched >= 16)
                {
                    MessageBoxResult res =
                        MessageBox.Show("성공! 다시 하겠습니까?", "Success!",
                        MessageBoxButton.YesNo);
                    if (res == MessageBoxResult.Yes)  // 초기화
                    {
                        RndReset();
                        BoardReset();
                        BoardSet();
                        matched = 0;
                    }
                    else
                        this.Close();
                }
            }
            else  // 같지 않다면
            {
                myTimer.Start();
            }
        }

 버튼 클릭시 메소드.

1. 첫번째 버튼 눌렀을 때 사진 불러오기

2. 두번째 버튼 눌렀을 때 사진 불러오기

3. 각각 비교하기.

4. if문을 통해 모두 다 match 성공했다면 MessageBox 띄워서 재시작 or 끝내기

   +else에서는 타이머 시작을 통해 그림 덮기

	private void BoardReset()
        {
            board.Children.Clear();
        }
        private void RndReset()
        {
            for (int i = 0; i < 16; i++)
                rnd[i] = 0;
        }

        Button first = null;
        Button second = null;
        private int matched;


        // 0~7까지의 그림 종류에 해당하는 번호
        // 각 번호는 2개씩 할당되어야 함
        private object TagSet()
        {
            Random r = new Random();
            while (true)
            {
                int n = r.Next(16);  // 0~15까지의 숫자
                if (rnd[n] == 0) // 처음 나온 숫자인지
                {
                    rnd[n] = 1;
                    return n % 8;
                }
            }
        }

BoardReset() 및 RndReset() 구현

보드 클리어. 랜덤 값 저장

TagSet()

- 랜덤 값으로 8(0~7)개의 수 총 16개의 수 할당.

	private Image MakeImage(string v)
        {
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.UriSource = new Uri(v, UriKind.Relative);
            bi.EndInit();

            Image myImage = new Image();
            myImage.Margin = new Thickness(10);
            myImage.Stretch = Stretch.Fill;
            myImage.Source = bi;

            return myImage;
        }

BitmapImage 형 객체 선언 및 이미지를 만들어서 이미지 리턴.

public partial class MainWindow : Window
    {
        int[] rnd = new int[16];   // TagSet()에서 사용할 배열
        DispatcherTimer myTimer = new DispatcherTimer();
    
        public MainWindow()
        {
            InitializeComponent();
            BoardSet();
            myTimer.Interval = new TimeSpan(0, 0, 0, 0, 750);
            myTimer.Tick += MyTimer_Tick;
        }

        private void MyTimer_Tick(object sender, EventArgs e)
        {
            myTimer.Stop();
            first.Content = MakeImage("../../images/check.png");
            second.Content = MakeImage("../../images/check.png");
            first = null;
            second = null;
        }

        private void BoardSet()
        {
            for (int i = 0; i < 16; i++)
            {
                Button btn = new Button();
                btn.Background = Brushes.White;
                btn.Margin = new Thickness(10);

                btn.Tag = TagSet();     // 랜덤하고 각 숫자가 2개씩
                btn.Content = MakeImage("../../images/check.png");  // 그림으로 대체될 것임

                // 버튼의 클릭 이벤트 설정
                btn.Click += Btn_Click;

                board.Children.Add(btn);
            }
        }

        private void Btn_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;

            string[] icon = {"딸기", "레몬", "모과", "배",
            "사과", "수박", "파인애플", "포도"};
            string fruitName = icon[(int)btn.Tag];

            if (first == null)  // 누른 버튼이 첫번째 버튼이라면
            {
                first = btn;
                btn.Content = MakeImage("../../images/" + fruitName + ".png");
                return;
            }
            else if (second == null) // 지금 누른 버튼이 두번째 버튼이라면
            {
                second = btn;
                btn.Content = MakeImage("../../images/" + fruitName + ".png");
            }
            else
            {
                return;
            }

            // 비교하기
            if ((int)first.Tag == (int)second.Tag)  // 같다
            {
                first = null;
                second = null;
                matched += 2;  // 매칭된 버튼의 개수
                if (matched >= 16)
                {
                    MessageBoxResult res =
                        MessageBox.Show("성공! 다시 하겠습니까?", "Success!",
                        MessageBoxButton.YesNo);
                    if (res == MessageBoxResult.Yes)  // 초기화
                    {
                        RndReset();
                        BoardReset();
                        BoardSet();
                        matched = 0;
                    }
                    else
                        this.Close();
                }
            }
            else  // 같지 않다면
            {
                myTimer.Start();
            }
        }

        private void BoardReset()
        {
            board.Children.Clear();
        }
        private void RndReset()
        {
            for (int i = 0; i < 16; i++)
                rnd[i] = 0;
        }

        Button first = null;
        Button second = null;
        private int matched;


        // 0~7까지의 그림 종류에 해당하는 번호
        // 각 번호는 2개씩 할당되어야 함
        private object TagSet()
        {
            Random r = new Random();
            while (true)
            {
                int n = r.Next(16);  // 0~15까지의 숫자
                if (rnd[n] == 0) // 처음 나온 숫자인지
                {
                    rnd[n] = 1;
                    return n % 8;
                }
            }
        }

        private Image MakeImage(string v)
        {
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.UriSource = new Uri(v, UriKind.Relative);
            bi.EndInit();

            Image myImage = new Image();
            myImage.Margin = new Thickness(10);
            myImage.Stretch = Stretch.Fill;
            myImage.Source = bi;

            return myImage;
        }
        

        
    }

전체 소스코드

'C#' 카테고리의 다른 글

048_WPF_Clock_C#  (0) 2022.06.12
047_Form_Clock_C#  (0) 2022.06.09
045_ECG,PPG(Gragh Control)  (0) 2022.06.09
044_Graph  (0) 2022.06.09
043_TwoChart  (0) 2022.06.09