Beispiel #1
0
            /**
             * Returns the length of this sequence
             */
            public int getLength()
            {
                int           len = 0;
                FieldTreeNode cur = this;

                do
                {
                    ++len;
                    cur = cur.parent;
                }while (cur != null);
                return(len);
            }
Beispiel #2
0
            /**
             * Returns a letter that did not exist in a field before or null if such a node is absent
             */
            public FieldTreeNode findNewLetter()
            {
                FieldTreeNode cur = this;

                do
                {
                    if (cur.isAdded)
                    {
                        return(cur);
                    }
                    cur = cur.parent;
                }while (cur != null);
                return(null);
            }
Beispiel #3
0
            /**
             * Determines whether this word contains a cell with coordinates (x; y)
             */
            public bool containsCoords(int x, int y)
            {
                FieldTreeNode cur = this;

                do
                {
                    if (cur.x == x && cur.y == y)
                    {
                        return(true);
                    }
                    cur = cur.parent;
                }while (cur != null);
                return(false);
            }
Beispiel #4
0
            public int prefixTreeIndex;  // index of this node in the prefix tree

            public FieldTreeNode(bool isAdded,
                                 bool newLetterUsed,
                                 FieldTreeNode parent,
                                 int x,
                                 int y,
                                 int letter,
                                 int prefixTreeIndex)
            {
                this.isAdded         = isAdded;
                this.newLetterUsed   = newLetterUsed;
                this.parent          = parent;
                this.x               = x;
                this.y               = y;
                this.letter          = letter;
                this.prefixTreeIndex = prefixTreeIndex;
            }
Beispiel #5
0
        public void move(FieldState state, ref Move move, Rules rules)
        {
            System.Threading.Thread.Sleep(150);
            if (optimalMove.Count == 0) // this holds only on the first move of the iteration
            {
                int nonDiagonalCounter = 0;
                // then find the optimal move
                int   width = state.Field.GetLength(0);
                int[] dx, dy;
                if (rules.AllowDiagonal == true)
                {
                    dx = new int[] { 1, 0, -1, 0, 1, 1, -1, -1 };
                    dy = new int[] { 0, 1, 0, -1, 1, -1, 1, -1 };
                }
                else
                {
                    dx = new int[] { 1, 0, -1, 0 };
                    dy = new int[] { 0, 1, 0, -1 };
                }
                for (int i = 0; i < width; ++i)
                {
                    for (int j = 0; j < width; ++j)
                    {
                        Stack <FieldTreeNode> st = new Stack <FieldTreeNode>();
                        if (state.Field[i, j] == '\0')
                        {
                            // if there is space in the current cell
                            for (int k = 0; k < 32; ++k)
                            {
                                // add every possible letter
                                if (prefixTree[0, k] != -1)
                                {
                                    st.Push(new FieldTreeNode(true, true, null, j, i, k, prefixTree[0, k]));
                                }
                            }
                        }
                        else
                        {
                            // there is only one possible start node
                            // if there are words that start with this letter
                            if (prefixTree[0, state.Field[i, j] - 'А'] != -1)
                            {
                                st.Push(new FieldTreeNode(false,
                                                          false,
                                                          null,
                                                          j,
                                                          i,
                                                          state.Field[i, j] - 'А',
                                                          prefixTree[0, state.Field[i, j] - 'А']));
                            }
                        }
                        while (st.Count > 0)
                        {
                            FieldTreeNode cur = st.Pop();
                            int           cx = cur.x, cy = cur.y;
                            // add all it's neighbours
                            for (int k = 0; k < dx.Length; ++k)
                            {
                                try
                                {
                                    if (!rules.AllowIntersections)
                                    {
                                        if (cur.containsCoords(cx + dx[k], cy + dy[k]))
                                        {
                                            continue;
                                        }
                                    }
                                    // if the neighbour contains a space and it can be filled with a new letter
                                    if (state.Field[cy + dy[k], cx + dx[k]] == '\0' && !cur.newLetterUsed)
                                    {
                                        for (int l = 0; l < 32; ++l)
                                        {
                                            if (prefixTree[cur.prefixTreeIndex, l] != -1)
                                            {
                                                st.Push(new FieldTreeNode(true,
                                                                          true,
                                                                          cur,
                                                                          cx + dx[k],
                                                                          cy + dy[k],
                                                                          l,
                                                                          prefixTree[cur.prefixTreeIndex, l]));
                                            }
                                        }
                                    }
                                    // if the neighbour contains a letter and there is a corresponding prefix
                                    if (isCapitalRussianLetter(state.Field[cy + dy[k], cx + dx[k]]) &&
                                        prefixTree[cur.prefixTreeIndex, state.Field[cy + dy[k], cx + dx[k]] - 'А'] != -1)
                                    {
                                        st.Push(new FieldTreeNode(false,
                                                                  cur.newLetterUsed,
                                                                  cur,
                                                                  cx + dx[k],
                                                                  cy + dy[k],
                                                                  state.Field[cy + dy[k], cx + dx[k]] - 'А',
                                                                  prefixTree[cur.prefixTreeIndex, state.Field[cy + dy[k], cx + dx[k]] - 'А']));
                                    }
                                }
                                catch (IndexOutOfRangeException)
                                {
                                    // this is OK, do nothing
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(ex.Message);
                                }
                            }
                            // check if cur is a word
                            if (isWord[cur.prefixTreeIndex] && cur.newLetterUsed == true)
                            {
                                if (!cur.containsDiagonal())
                                {
                                    ++nonDiagonalCounter;
                                }
                                // then add a corresponding move to our list of moves
                                FieldTreeNode newLetter = cur.findNewLetter();
                                Stack <Move>  newWord   = new Stack <Move>();
                                Move          lol       = new Move();
                                lol.Action = ActionType.EndTurn;
                                newWord.Push((Move)lol.Clone());
                                string word = "";
                                while (cur != null)
                                {
                                    word = (char)(cur.letter + 'А') + word;

                                    lol.Action = ActionType.SelectLetter;
                                    lol.X      = cur.x;
                                    lol.Y      = cur.y;
                                    newWord.Push((Move)lol.Clone());
                                    cur = cur.parent;
                                }
                                if (word == "ОСА")
                                {
                                    int q = 0;
                                }
                                lol.Action = ActionType.EnterLetter;
                                lol.X      = newLetter.x;
                                lol.Y      = newLetter.y;
                                lol.Letter = (char)(newLetter.letter + 'А');
                                newWord.Push((Move)lol.Clone());
                                // we cannot place words from ProhibitedWords, so check this
                                if (!state.ProhibitedWords.Contains(word))
                                {
                                    words.Add(word);
                                    possibleMoves.Add(newWord);
                                }
                            }
                        }
                    }
                }
                if (possibleMoves.Count == 0) // we have not found any possible word
                {
                    // in this case we can only pass a turn
                    Move tmp = new Move();
                    tmp.Action = ActionType.PassTurn;
                    optimalMove.Push(tmp);
                }
                else
                {
                    possibleMoves.Sort((list1, list2) => list1.Count - list2.Count);
                    int optimalIndex = 0;
                    switch (str)
                    {
                    case StrategyStrength.Easy:
                        optimalIndex = 0;
                        break;

                    case StrategyStrength.Medium:
                        optimalIndex = possibleMoves.Count / 2;
                        break;

                    case StrategyStrength.Hard:
                        optimalIndex = possibleMoves.Count - 1;
                        break;
                    }
                    optimalMove = possibleMoves[optimalIndex];
                }
                move = optimalMove.Pop();
            }
            else
            {
                move = optimalMove.Pop();
                if (optimalMove.Count == 0)
                {
                    possibleMoves.Clear();
                }
            }
            return;
        }
Beispiel #6
0
        // adds words that are present on the field to prohibitedWords;
        // used by the last story
        private void recountWords()
        {
            int nonDiagonalCounter = 0;
            // then find the optimal move
            int width = State.Field.GetLength(0);

            int[] dx, dy;
            if (Rules.AllowDiagonal == true)
            {
                dx = new int[] { 1, 0, -1, 0, 1, 1, -1, -1 };
                dy = new int[] { 0, 1, 0, -1, 1, -1, 1, -1 };
            }
            else
            {
                dx = new int[] { 1, 0, -1, 0 };
                dy = new int[] { 0, 1, 0, -1 };
            }
            for (int i = 0; i < width; ++i)
            {
                for (int j = 0; j < width; ++j)
                {
                    Stack <FieldTreeNode> st = new Stack <FieldTreeNode>();
                    if (State.Field[i, j] != '\0')
                    {
                        // there is only one possible start node
                        // if there are words that start with this letter
                        if (prefixTree[0, State.Field[i, j] - 'А'] != -1)
                        {
                            st.Push(new FieldTreeNode(false,
                                                      false,
                                                      null,
                                                      j,
                                                      i,
                                                      State.Field[i, j] - 'А',
                                                      prefixTree[0, State.Field[i, j] - 'А']));
                        }
                    }
                    while (st.Count > 0)
                    {
                        FieldTreeNode cur = st.Pop();
                        int           cx = cur.x, cy = cur.y;
                        // add all it's neighbours
                        for (int k = 0; k < dx.Length; ++k)
                        {
                            try
                            {
                                if (!Rules.AllowIntersections)
                                {
                                    if (cur.containsCoords(cx + dx[k], cy + dy[k]))
                                    {
                                        continue;
                                    }
                                }
                                // if the neighbour contains a letter and there is a corresponding prefix
                                if (isCapitalRussianLetter(State.Field[cy + dy[k], cx + dx[k]]) &&
                                    prefixTree[cur.prefixTreeIndex, State.Field[cy + dy[k], cx + dx[k]] - 'А'] != -1)
                                {
                                    st.Push(new FieldTreeNode(false,
                                                              cur.newLetterUsed,
                                                              cur,
                                                              cx + dx[k],
                                                              cy + dy[k],
                                                              State.Field[cy + dy[k], cx + dx[k]] - 'А',
                                                              prefixTree[cur.prefixTreeIndex, State.Field[cy + dy[k], cx + dx[k]] - 'А']));
                                }
                            }
                            catch (IndexOutOfRangeException)
                            {
                                // this is OK, do nothing
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message);
                            }
                        }
                        // check if cur is a word
                        if (isWord[cur.prefixTreeIndex])
                        {
                            if (!cur.containsDiagonal())
                            {
                                ++nonDiagonalCounter;
                            }
                            // then add a corresponding move to our list of moves
                            string word = "";
                            while (cur != null)
                            {
                                word = (char)(cur.letter + 'А') + word;
                                cur  = cur.parent;
                            }
                            State.ProhibitedWords.Add(word);
                        }
                    }
                }
            }
        }