[WPF] 영단어 맞추기 게임

jckim22·2024년 7월 5일

[C#] Study

목록 보기
3/4
<Window x:Class="영어단어맞추기.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:영어단어맞추기"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0">
            <Label Content="{Binding WrongStatus}"
                   FontWeight="Bold"
                   HorizontalAlignment="Center"
                   ></Label>
            <Label Content="{Binding SelKor}"
                   FontSize="30"
                   HorizontalAlignment="Center"
                   ></Label>
            <Label Content="{Binding SelEng}"
                   FontSize="40"
                   HorizontalAlignment="Center"
                   ></Label>
            <Label Content="{Binding Message}"
                   FontWeight="Bold"
                   Foreground="White"
                   Background="Red"
                   HorizontalContentAlignment="Center"
                   ></Label>
            <Button Content="다시하기"
                    HorizontalAlignment="Center"
                    Width="100" Margin="10"
                    Click="Button_Click">
                </Button>
        </StackPanel>
        <UniformGrid Grid.Row="1">
            <ItemsControl Name="ic">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Columns="10"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button
                            Content="{Binding .}"
                            FontSize="30"
                            FontWeight="Bold"
                            Background="Salmon"
                            Foreground="White"
                            Margin="10"
                            Click="Button_Click_1"
                            />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </UniformGrid>
    </Grid>
</Window>
namespace 영어단어맞추기
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler? PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if(handler != null) handler(this, new PropertyChangedEventArgs(name));
        }
        private string wrongStatus;
        private string selEng;
        private string selKor;
        private string message;
        private List<char> btns = new List<char>();

        public string WrongStatus {
            get => wrongStatus;
            set
            {
                wrongStatus = value;
                OnPropertyChanged("WrongStatus");
            }
        }

        public string SelEng
        {
            get => selEng;
            set
            {                
                selEng = value;
                OnPropertyChanged("SelEng");             
            }
        }


        public string SelKor
        {
            get => selKor;
            set
            {
                selKor = value;
                OnPropertyChanged("SelKor");
            }
        }


        public string Message
        {
            get => message;
            set
            {
                message = value;
                OnPropertyChanged("Message");
            }
        }
        List<char> SelWord = new List<char>();
        List<string> words = new List<string>()
        {
            "boy,소년",
            "school,학교",
            "fish,물고기",
            "car,자동차",
            "book,책"
        };

        int wrong = 0;
        int maxWrong = 3;
        string compareWord = string.Empty;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            btns.AddRange("abcdefghijklnmopqrstuvwxyz");
            ic.ItemsSource = btns;
            RandomWord();
            ChangeWord(SelEng, SelWord);
            WrongStatus = $"틀린횟수: {wrong} of {maxWrong}";
        }

        private void ChangeWord(string selEng, List<char> selWord)
        {
            char[] result = selEng.Select(x => (selWord.IndexOf(x) >= 0 ? x : '*')).ToArray();
            SelEng = string.Join(' ', result);
        }

        private void RandomWord()
        {
            string[] selChar = words[new Random().Next(0, words.Count)].Split(",");
            SelEng = selChar[0];
            SelKor = selChar[1];
            compareWord = selEng;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            wrong = 0;
            SelWord = new List<char>();
            RandomWord();
            ChangeWord(SelEng, SelWord);
            Message = "알파벳을 선택하여 주세요";
            Status();
            foreach (var a in ic.Items)
            {
                var btn = (UIElement)ic.ItemContainerGenerator.ContainerFromItem(a);
                if (btn != null)
                {
                    btn.IsEnabled = true;
                }
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            if (btn != null)
            {
                var result = btn.Content.ToString();
                CheckWord(result[0]);
            }
        }

        private void CheckWord(char v)
        {
            if(SelWord.IndexOf(v) == -1)
            {
                SelWord.Add(v);
            }
            if(compareWord.IndexOf(v) >= 0)
            {
                ChangeWord(compareWord, SelWord);
                CheckWin();
            }
            else if (compareWord.IndexOf(v) == -1)
            {
                wrong++;
                Status();
                CheckLose();

            }
        }

        private void Status()
        {
            WrongStatus = $"틀린횟수: {wrong} of {maxWrong}";
        }

        private void CheckWin()
        {
            if (compareWord == SelEng.Replace(" ", ""))
            {
                Message = "You Win!";
                MessageBox.Show("정답!");
                foreach (var a in ic.Items)
                {
                    var btn = (UIElement)ic.ItemContainerGenerator.ContainerFromItem(a);
                    if (btn != null)
                    {
                        btn.IsEnabled = false;
                    }
                }
            }
        }

        private void CheckLose()
        {
            if (wrong == maxWrong)
            {
                Message = "You Lost!";
                foreach(var a in ic.Items)
                {
                    var btn = (UIElement)ic.ItemContainerGenerator.ContainerFromItem(a);
                    if(btn != null)
                    {
                        btn.IsEnabled = false;
                    }
                }
            }
        }
    }
}
  • 데이터를 바인딩하는 것에 주목해보자
  • get, set property를 사용하면 앞 대문자를 사용해서 변수처럼 대입연산자 사용하듯이 게터 세터를 사용할 수 있다.
  • 물론 위 예제처럼 set을 커스터마이징 할 수 있다.
  • INotifyPropertyChanged는 인터페이스인데 데이터 컨텍스트가 수정되면 실행될 메서드를 구현한다.
  • OnPropertyChanged 메서드를 구현했고 세터마다 이 메서드를 호출함으로서 변경사항을 바로 반영한다.
  • ItemContainerGenerator.ContainerFromItem으로 가져온 Item을 UIElement로 형변환 한 뒤 다룰 수 있다.
  • 기타 로직들은 이해만 해보자
profile
개발/보안

0개의 댓글