Skip to content

Board класа

andrejdaskalov edited this page Jun 29, 2022 · 1 revision

Board класата ја содржи бизнис логиката на играта и податочните структури. Содржи и важни поможни методи за работење на играта.

Податочни структури

За лесно исцртување на самиот простор за играње, Board содржи матрица од LetterBox. public LetterBox[][] LetterGrid;.
Ја користи матрицата за пресметување на позицијата за исцртување на секое LetterBox.
Истите LetterBoxs се исто така организирани и во структури од вгнездени двојно-пповрзани листи, за лесна итерација низ самите LetterBox без потреба за одржување бројачи.
public LinkedListNode<LetterBox> CurrentLetter; ја преставува моментално селектираната буква. Се чува замотана во LinkedListNode бидејќи ова ни ги задржува релациите на поврзана листа и можеме лесно да повикаме Next() за да се придвижиме на следната буква.
public LinkedListNode<LinkedList<LetterBox>> CurrentWord; го преставува зборот (редицата) која е моментално во фокус. Замотана е во LinkedListNode за да може лесно да се движиме на следен збор.
public LinkedList<LinkedList<LetterBox>> WordsOnTable; е листа од сите зборови(а тие самите се листа од букви), и ја преставува целата табла на играње во форма на поврзани вгнезгени листи.

Иницијализација на податочни структури

Иницијализација на матрицата, се пресметува и просторот меѓу квадратите и се додава и отстапување верикално и хоризонтално

        private LetterBox[][] ConstructGrid()
        {
            var letterGrid = new LetterBox[6][];
            for (int i = 0; i < 6; i++)
            {
                letterGrid[i] = new LetterBox[5];

                for (int j = 0; j < 5; j++)
                {
                    letterGrid[i][j] = new LetterBox(j * LetterBox.LetterBoxSize + (j + 1) * Padding + XOffset,
                        i * LetterBox.LetterBoxSize + (i + 1) * Padding + YOffset);
                }
            }
            return letterGrid;
        }

иницијализација на вгнездените листи

        private void CreateLists()
        {
            WordsOnTable = new LinkedList<LinkedList<LetterBox>>();
            for (int i = 0; i < 6; i++)
            {
                LinkedList<LetterBox> letterList = new LinkedList<LetterBox>();
                for (int j = 0; j < 5; j++)
                {
                    letterList.AddLast(LetterGrid[i][j]);
                }
                WordsOnTable.AddLast(letterList);
            }
        }

Десеријализација на листи

private void GetWordList()
        {
            BinaryFormatter formatter = new BinaryFormatter();
            Stream stream;
            using (stream = new MemoryStream(Resources.wordlist))
            {
                WordList = (List<string>)formatter.Deserialize(stream);
            }
        }

методата користи MemoryStream за да ги десеријализира листите. Дадениот пример се однесува на преземање на wordlist, истиот процес е и за answerlist.

Процесирање на збор

класата содржи метод ProcessWord() кој имплементира алгоритам за процесирање на внесениот збор според дадените правила на игра.
Алгоритамот ги извршува следниве чекори:

  1. итерирај низ внесениот збор сподерувајќи ја секоја буква со соодветната буква на иста позиција во точниот збор и притоа:
  • замени ја буквата во точниот збор со - доколку се совпаѓаат (ова е со цел да не подоцна да не проверува букви дали се Guessed иако веќе биле означени Positioned) и означи го со состојба Positioned
  1. итерирај низ внесениот збор вторпат и провери дали зборот се содржи во точниот збор, притоа
  • замени ја буквата во точниот збор со - доколку се содржи во точниот збор (со цел да не се брои двапати) и означи го со состојба Guessed
  • инаку означи го со Incorrect

Имплементацијата на опишаниот алгоритам:

public void ProcessWord()
        {
            int i = 0;
            int correctLetters = 0;
            StringBuilder sb = new StringBuilder(CorrectWord);

            //First iterate through the word to check for correctly positioned letters, and mark accordingly
            //Mark off in sb if it's correctly positioned, so it doesn't get marked twice in the next for loop
            foreach (var letterBox in CurrentWord.Value)
            {
                if (sb.ToString().IndexOf(letterBox.Letter.ToLower()) == i)
                {
                    letterBox.State = LetterBoxState.Positioned;
                    _form.virtualKeyboard.KeyDictionary[letterBox.Letter.ToLower()].State = LetterBoxState.Positioned;
                    correctLetters++;
                    if (correctLetters == 5)
                    {
                        _form.GameWon();
                    }
                    sb = sb.Replace(letterBox.Letter.ToLower(), "-", i, 1);
                }

                i++;
            }

            //iterate through word a second time, now marking each letter as Guessed or Incorrect
            //while marking off the Guessed letters so they do not get counted twice
            i = 0;
            foreach (var letterBox in CurrentWord.Value)
            {
                if (letterBox.State != LetterBoxState.Positioned)
                {
                    if (sb.ToString().Contains(letterBox.Letter.ToLower()))
                    {
                        letterBox.State = LetterBoxState.Guessed;
                        _form.virtualKeyboard.KeyDictionary[letterBox.Letter.ToLower()].State = LetterBoxState.Guessed;
                        sb = sb.Replace(letterBox.Letter.ToLower(), "-", sb.ToString().IndexOf(letterBox.Letter.ToLower()), 1);
                    }
                    else
                    {
                        letterBox.State = LetterBoxState.Incorrect;
                        _form.virtualKeyboard.KeyDictionary[letterBox.Letter.ToLower()].State = LetterBoxState.Incorrect;

                    }
                }
                
                i++;
            }

        }