示例#1
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;
        }