Exemplo n.º 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;
        }
Exemplo n.º 2
0
        private void processPlayer(Player player, int currentIndex)
        {
            timeIsUp = false;
            bool correctEndTurn = false;
            Move move           = new Move();

            //time = new TimeSpan(0, Rules.TimeLimit, 0);
            time = new TimeSpan(0, Rules.TimeLimit, 0);
            gamingForm.updateTimer(time);
            MessageBox.Show("Ходит игрок " + player.Name);
            gamingForm.updatePlayersScore(Players, currentIndex);

            do
            {
                if (timeIsUp == false)
                {
                    gamingForm.updateForm(State, Rules);
                    player.Strategy.move(State, ref move, Rules);
                }
                else
                {
                    move.Action = ActionType.PassTurn;
                }
                switch (move.Action)
                {
                case ActionType.EnterLetter:
                {
                    int x = move.X, y = move.Y;
                    int width = State.Field.GetLength(0);
                    if (x < 0 || x >= width || y < 0 || y >= width)
                    {
                        // indices out of range
                        break;
                    }
                    move.Letter = Char.ToUpper(move.Letter);
                    if (!isCapitalRussianLetter(move.Letter))
                    {
                        // incorrect character
                        break;
                    }
                    if (State.NewX != -1 && State.NewY != -1)
                    {
                        // user already entered new letter
                        break;
                    }
                    State.NewX        = x;
                    State.NewY        = y;
                    State.Field[y, x] = move.Letter;
                }
                break;

                case ActionType.SelectLetter:
                {
                    int  wordLength = State.X.Count;
                    int  x = move.X, y = move.Y;
                    bool isCorrect = true;
                    int  width     = State.Field.GetLength(0);
                    if (x < 0 || x >= width || y < 0 || y >= width)
                    {
                        // indices out of range
                        break;
                    }
                    char nullLetter = '\0';
                    if (State.Field[y, x] == nullLetter)
                    {        //user must select only letters;
                        break;
                    }
                    if (wordLength == 0)
                    {
                        State.X.Add(x);
                        State.Y.Add(y);
                        break;
                    }
                    if (!Rules.AllowIntersections)
                    {
                        for (int i = 0; i < wordLength; i++)
                        {
                            if (State.X[i] == x && State.Y[i] == y)
                            {
                                //new coordinate intersects with the word
                                isCorrect = false;
                                break;
                            }
                        }
                        if (!isCorrect)
                        {
                            break;
                        }
                    }
                    if (Rules.isNeighbours(x, y, State.X[wordLength - 1], State.Y[wordLength - 1]))
                    {
                        State.X.Add(x);
                        State.Y.Add(y);
                    }
                    else
                    {
                        break;
                    }
                }
                break;

                case ActionType.EndTurn:
                {
                    bool   foundLetter = false;
                    string word        = "";
                    //check if the word contains the newly enter letter
                    if (State.NewX == -1 && State.NewY == -1)
                    {
                        MessageBox.Show("Введите букву");
                        break;
                    }

                    if (State.X.Count == 0 && State.Y.Count == 0)
                    {
                        MessageBox.Show("Выберите слово");
                        break;
                    }

                    for (int i = 0; i < State.X.Count; i++)
                    {
                        if (State.X[i] == State.NewX && State.Y[i] == State.NewY)
                        {
                            foundLetter = true;
                            break;
                        }
                    }

                    if (!foundLetter)
                    {
                        MessageBox.Show("Слово не содержит поставленную букву");
                        resetTurn();
                        break;
                    }

                    for (int i = 0; i < State.X.Count; i++)
                    {
                        int x = State.X[i];
                        int y = State.Y[i];
                        word += State.Field[y, x];
                    }

                    if (!wordBase.Contains(word))
                    {
                        MessageBox.Show(String.Format("База не содержит слова - {0}", word));
                        resetTurn();
                        break;
                    }

                    if (State.ProhibitedWords.Contains(word))
                    {
                        MessageBox.Show("Cлово " + word + " уже было");
                        resetTurn();
                        break;
                    }

                    State.ProhibitedWords.Add(word);

                    player.Score += word.Length;

                    State.NewX = -1;
                    State.NewY = -1;
                    State.X.Clear();
                    State.Y.Clear();

                    ListViewItem item = new ListViewItem(word);
                    item.ForeColor = player.PlayerColor;
                    gamingForm.addNewWord(item);
                    consequtiveTurnPasses = 0;
                    correctEndTurn        = true;
                    return;
                }
                break;

                case ActionType.Reset:
                {
                    resetTurn();
                }
                break;

                case ActionType.PassTurn:
                {
                    consequtiveTurnPasses++;
                    resetTurn();
                    return;
                }
                break;
                }
            }while (!((move.Action == ActionType.EndTurn && correctEndTurn == true) || move.Action == ActionType.PassTurn));
            // if the user chose non-existing word, we should ask him for another word instead of exitting
            // the very last turn will not be shown otherwise
            gamingForm.updatePlayersScore(Players, currentIndex);
        }