Exemple #1
0
        // На основе вывода этого метода делается вывод о том, какой костью соперник с наименьшей вероятностью обладает. Чем больше число, тем меньше вероятность.
        private int[] CalculateReversedProbabilitiesOfEnemyHavingEachCountsOfSpotsOnTilesInHand()
        {
            int[] reversedProbabilities = new int[7];

            CountSpots(ref reversedProbabilities, MTable.GetGameCollection());
            CountSpots(ref reversedProbabilities, lHand);

            return(reversedProbabilities);
        }
Exemple #2
0
        //Используется максимально примитивная логика: мы проходим по всем доминошкам в нашей руке
        //и выставляем первую попавшуюся, которую можно пристроить
        public override bool MakeStep(out MTable.SBone sb, out bool end)
        {
            //Получаем состояние стола
            List <MTable.SBone> lTableCondition = MTable.GetGameCollection();

            //Кость на левом  конце цепочки
            MTable.SBone sLeft = lTableCondition[0];
            //Кость на правом конце цепочки
            MTable.SBone sRight = lTableCondition[lTableCondition.Count - 1];

            //Просматриваем все домино в руке
            for (int i = 0; i < lHand.Count; ++i)
            {
                //Если её можно поставить слева
                if (lHand[i].Second == sLeft.First || lHand[i].First == sLeft.First)
                {
                    //То говорим, что мы выбираем её
                    sb = lHand[i];
                    //Удаляем её из руки
                    lHand.RemoveAt(i);
                    //Указываем куда мы её ставим
                    end = false;
                    //Заканчиваем ход
                    return(true);
                }
                //Если её можно поставить справа
                if (lHand[i].Second == sRight.Second || lHand[i].First == sRight.Second)
                {
                    //То говорим, что мы выбираем её
                    sb = lHand[i];
                    //Удаляем её из руки
                    lHand.RemoveAt(i);
                    //Указываем куда мы её ставим
                    end = true;
                    //Заканчиваем ход
                    return(true);
                }
            }

            //Добираем новые кости с базара, пока не сможем их поставить
            //Переменная для добираемой кости
            MTable.SBone sbNew;

            //Пока можно добирать из базара берём кость
            while (MTable.GetFromShop(out sbNew))
            {
                //Если её можно поставить слева
                if (sbNew.Second == sLeft.First || sbNew.First == sLeft.First)
                {
                    //То говорим, что мы выбираем её
                    sb = sbNew;
                    //Указываем куда мы её ставим
                    end = false;
                    //Заканчиваем ход
                    return(true);
                }
                //Если её можно поставить справа
                if (sbNew.Second == sRight.Second || sbNew.First == sRight.Second)
                {
                    //То говорим, что мы выбираем её
                    sb = sbNew;
                    //Указываем куда мы её ставим
                    end = true;
                    //Заканчиваем ход
                    return(true);
                }
                //Если её нельзя положить на стол, то кладем её в руку
                lHand.Add(sbNew);
            }

            //Если мы не можем сделать ход, то в данные параметры загоняем любую чушь, которую можно загнать
            sb.First  = 322;
            sb.Second = 322;
            end       = true;

            //И возвращаем, что ход сделать нельзя
            return(false);
        }
Exemple #3
0
        private int leftest, rightest;                                  // Содержат два возможных хода


        // Сделать ход: возвращает false, если ход сделать нельзя; sb - чем ходить, End: true = направо
        public override bool MakeStep(out MTable.SBone sb, out bool End)
        {
            var table      = MTable.GetGameCollection();
            int myScore    = GetScore(),
                tableScore = GetSBoneListScore(table);

            bool FishIsAnOption = myScore < 168 - myScore - tableScore; // Разумно ли будет походить для рыбы (меньше ли очков, чем будет у противника при рыбе)

            leftest  = table[0].First;                                  // точки, находящиеся на краях
            rightest = table[table.Count - 1].Second;

            List <MTable.SBone> Variants;

            // Получение необходимых доминошек из базара
            while ((Variants = GetVariantsForStep()).Count == 0)
            {
                MTable.SBone tile;
                if (!MTable.GetFromShop(out tile))                      // если базар пуст, а ход не сделать
                {
                    sb  = new MTable.SBone();
                    End = false;
                    return(false);
                }
                lHand.Add(tile);
            }

            // Получаем вероятности неналичия у соперника кости с данными точками.
            probs = CalculateReversedProbabilitiesOfEnemyHavingEachCountsOfSpotsOnTilesInHand();

            // Засовываем кости в обёртку
            var sTiles = new List <STiles>();

            foreach (var tile in Variants)
            {
                sTiles.Add(new STiles(tile, probs, leftest, rightest));
            }

            var cst = new CompSTiles <STiles>();            // Позволяет сортировать обёрнутые доминошки по их весу


            // Пытаемся сделать рыбу:
            if (FishIsAnOption && probs[leftest] == 7)             // Если левыый из концов заблокирован для соперника
            {
                foreach (var tile in Variants)
                {
                    if (tile.First == rightest && probs[tile.Second] == 7 || tile.Second == rightest && probs[tile.First] == 7)
                    {
                        sb = tile;
                        lHand.Remove(sb);
                        End = true;
                        return(true);
                    }
                }
            }
            else if (FishIsAnOption && probs[rightest] == 7)                       // Если правый из концов заблокирован для соперника и выгодно сделать рыбу
            {
                foreach (var tile in Variants)
                {
                    if (tile.First == leftest && probs[tile.Second] == 7 || tile.First == leftest && probs[tile.Second] == 7)
                    {
                        sb = tile;
                        lHand.Remove(sb);
                        End = false;
                        return(true);
                    }
                }
            }

            foreach (var item in sTiles)
            {
                item.wNextPoss = CheckPOSSIBOfNextMoves(ListWithout(lHand, item.tile), leftest, rightest, 0, 0);
            }

            sTiles.Sort(cst);             //сортировка по весу доминошек

            // Выбор самая выгодная по весу
            if (FishIsAnOption || sTiles[0].wEnemyHasnt > KOEFF_FOR_ASSURED_MOVES_COUNT)                // чтобы не зажать самого себя
            {
                sb = sTiles[0].tile;
            }
            else if (sTiles.Count > 1)
            {
                sb = sTiles[(sTiles[0].wSpots > sTiles[1].wSpots) ? 0 : 1].tile;
            }
            else
            {
                sb = sTiles[0].tile;
            }


            lHand.Remove(sb);             // Остаётся только убрать выбранную доминошку из руки и походить ей

            End = DecideSide(sb, leftest, rightest, probs);
            return(true);
        }
Exemple #4
0
        public override bool MakeStep(out MTable.SBone sb, out bool end)
        {
            _i++;
            if (_i == 1)
            {
                GenerateDomino(AllDomino);
            }

            //Получаем состояние стола
            List <MTable.SBone> lTableCondition = MTable.GetGameCollection();

            //Кость на левом  конце цепочки
            MTable.SBone sLeft = lTableCondition[0];
            if (lTableCondition.Contains(sLeft))
            {
                AllDomino.Remove(sLeft);
            }


            MTable.SBone sRight = lTableCondition[lTableCondition.Count - 1];
            if (lTableCondition.Contains(sRight))
            {
                AllDomino.Remove(sRight);
            }


            List <Tuple <MTable.SBone, bool, int> > HandDomino = new List <Tuple <MTable.SBone, bool, int> >();

            //Просматриваем все домино в руке

            for (int i = 0; i < lHand.Count; i++)
            {
                //Если её можно поставить слева
                if (lHand[i].Second == sLeft.First || lHand[i].First == sLeft.First)
                {
                    end = false;
                    int k = 0;
                    for (int j = 0; j < AllDomino.Count; j++)
                    {
                        if ((AllDomino[j].First == lHand[i].First) || (AllDomino[j].Second == lHand[i].Second))
                        {
                            k++;
                        }
                    }
                    HandDomino.Add(Tuple.Create(lHand[i], end, k));
                    //    end = false; слева
                }
                //Если её можно поставить справа
                if (lHand[i].Second == sRight.Second || lHand[i].First == sRight.Second)
                {
                    int k = 0;
                    for (int j = 0; j < AllDomino.Count; j++)
                    {
                        if ((AllDomino[j].First == lHand[i].First) || (AllDomino[j].Second == lHand[i].Second))
                        {
                            k++;
                        }
                    }
                    end = true;
                    HandDomino.Add(Tuple.Create(lHand[i], end, k));
                    // end = true; справа
                }
            }

            // анализ руки и выставление доминошки
            // взять минимальную доминошку из нашей руки и она минмальная в общей куче
            if (HandDomino.Count != 0)
            {
                int min = 10;
                sb  = HandDomino[0].Item1;
                end = false;
                int b = 0;
                for (int i = 0; i < HandDomino.Count; i++)
                {
                    if (HandDomino[i].Item3 < min)
                    {
                        min = HandDomino[i].Item1.Second;
                        sb  = HandDomino[i].Item1;
                        b   = i;
                        end = HandDomino[i].Item2;
                    }
                }
                if (min != 10)
                {
                    HandDomino.RemoveAt(b);
                    lHand.Remove(sb);
                    return(true);
                }
            }

            //Добираем новые кости, пока не сможем их поставить
            MTable.SBone sbNew;


            while (MTable.GetFromShop(out sbNew))
            {
                //Если её можно поставить слева
                if (sbNew.Second == sLeft.First || sbNew.First == sLeft.First)
                {
                    sb  = sbNew;
                    end = false;
                    return(true);
                }
                //Если её можно поставить справа
                if (sbNew.Second == sRight.Second || sbNew.First == sRight.Second)
                {
                    sb = sbNew;

                    end = true;
                    //Заканчиваем ход
                    return(true);
                }
                //Если её нельзя положить на стол, то кладем её в руку
                lHand.Add(sbNew);
            }


            sb.First  = 400;
            sb.Second = 400;
            end       = true;

            // ход сделать нельзя
            return(false);
        }
Exemple #5
0
 public void PrintAll()
 {
     MTable.PrintAll(lHand);
 }
Exemple #6
0
 public static List <State> PlayRound(bool firstIsFirst)
 {
     return(MTable.RunRound(firstIsFirst));
 }
Exemple #7
0
        //Сделать ход
        public override bool MakeStep(out MTable.SBone sb, out bool end)
        {
            #region TableLoad

            //Получаем состояние стола
            List <MTable.SBone> lTableCondition = MTable.GetGameCollection();

            //Кости на концах цепочки
            MTable.SBone sLeft  = lTableCondition[0];
            MTable.SBone sRight = lTableCondition[lTableCondition.Count - 1];

            //Standardize(ref sLeft );
            //Standardize(ref sRight);

            //Получение числа костей на столе, в руке оппонента
            int iShopBoneCount  = MTable.GetShopCount();
            int iEnemyBoneCount = 28 - _lHand.Count - iShopBoneCount - lTableCondition.Count;

            #endregion

            //Поиск изменений стола с предыдущего хода
            #region TableUpdate

            //Первичная инициализация
            if (!_pInit)
            {
                foreach (var item in lTableCondition)
                {
                    var t = item;
                    Standardize(ref t);
                    DominoIsUsed(t);
                }
                foreach (var item in _lHand)
                {
                    DominoIsUsed(item);
                }
            }

            //Подсчет количества новых домино в руке оппонента
            int iEnemyBoneCountDeltha = iEnemyBoneCount - _pEnemyBoneCount;

            DominoIsUsed(sLeft);
            DominoIsUsed(sRight);

            if (iEnemyBoneCountDeltha > 0)
            {
                for (ushort i = 0; i < 7; i++)
                {
                    for (ushort j = 0; j < 7; j++)
                    {
                        if (j > i)
                        {
                            break;
                        }
                        if (!_lsbUsed.Contains(new MTable.SBone {
                            First = i, Second = j
                        }) && !_lsbUsed.Contains(new MTable.SBone {
                            First = j, Second = i
                        }) && _pInit)
                        {
                            _iProbabilityTable[j, i] += iEnemyBoneCountDeltha;
                            if (i != j)
                            {
                                _iProbabilityTable[i, j] += iEnemyBoneCountDeltha;
                            }
                        }
                    }
                }
            }
            else if (iEnemyBoneCountDeltha != 0)
            {
                for (ushort i = 0; i < 7; i++)
                {
                    for (ushort j = 0; j < 7; j++)
                    {
                        if (j > i)
                        {
                            break;
                        }
                        if (!_lsbUsed.Contains(new MTable.SBone {
                            First = i, Second = j
                        }) && !_lsbUsed.Contains(new MTable.SBone {
                            First = j, Second = i
                        }) && _iProbabilityTable[i, j] == _pEnemyBoneCount)
                        {
                            _iProbabilityTable[i, j] -= 1;
                            if (i != j)
                            {
                                _iProbabilityTable[j, i] -= 1;
                            }
                        }
                    }
                }
            }

            if (!_pInit)
            {
                _pInit = !_pInit;
            }
            else if (iEnemyBoneCountDeltha >= 0)
            {
                if (Equals(_pLeft, sLeft))
                {
                    if (!Equals(_pRight, sRight))
                    {
                        DominoIsUsed(sRight);
                        for (ushort i = 0; i < 7; i++)
                        {
                            if (!_lsbUsed.Contains(new MTable.SBone {
                                First = i, Second = _pLeft.First
                            }) &&
                                !_lsbUsed.Contains(new MTable.SBone {
                                First = _pLeft.First, Second = i
                            }))
                            {
                                DominoIsntInEHand(new MTable.SBone {
                                    First = i, Second = _pLeft.First
                                });
                            }
                            if (!_lsbUsed.Contains(new MTable.SBone {
                                First = i, Second = _pRight.Second
                            }) &&
                                !_lsbUsed.Contains(new MTable.SBone {
                                First = _pRight.Second, Second = i
                            }))
                            {
                                DominoIsntInEHand(new MTable.SBone {
                                    First = i, Second = _pRight.Second
                                });
                            }
                        }
                    }
                }
                else if (!Equals(_pLeft, sLeft))
                {
                    DominoIsUsed(sLeft);
                    for (ushort i = 0; i < 7; i++)
                    {
                        if (!_lsbUsed.Contains(new MTable.SBone {
                            First = i, Second = _pLeft.First
                        }) &&
                            !_lsbUsed.Contains(new MTable.SBone {
                            First = _pLeft.First, Second = i
                        }))
                        {
                            DominoIsntInEHand(new MTable.SBone {
                                First = i, Second = _pLeft.First
                            });
                        }
                        if (!_lsbUsed.Contains(new MTable.SBone {
                            First = i, Second = _pRight.Second
                        }) &&
                            !_lsbUsed.Contains(new MTable.SBone {
                            First = _pRight.Second, Second = i
                        }))
                        {
                            DominoIsntInEHand(new MTable.SBone {
                                First = i, Second = _pRight.Second
                            });
                        }
                    }
                }
            }
            #endregion

            //Получаем все домино в руке, которые можно использовать на этот ход
            List <TurnOption> ltoUsefulDominoes = GetUsefulDomino(_lHand, sLeft, sRight);

            //Обновление сохраняемых параметров
            _pLeft  = sLeft;
            _pRight = sRight;

            if (ltoUsefulDominoes.Count != 0)
            {
                TurnOption bestTo = GetBt(ltoUsefulDominoes);
                sb  = bestTo.Bone;
                end = bestTo.End;

                SaveTable(ref sb, end, iEnemyBoneCount, end ? sRight.Second : sLeft.First);
                _lHand.Remove(sb);
                sb.Exchange();
                _lHand.Remove(sb);
                return(true);
            }

            MTable.SBone sbNew;

            while (MTable.GetFromShop(out sbNew))
            {
                DominoIsUsed(sbNew);
                List <MTable.SBone> lNew = new List <MTable.SBone>
                {
                    sbNew
                };
                ltoUsefulDominoes = GetUsefulDomino(lNew, sLeft, sRight);

                if (ltoUsefulDominoes.Count != 0)
                {
                    TurnOption bestTo = GetBt(ltoUsefulDominoes);
                    sb  = bestTo.Bone;
                    end = bestTo.End;

                    SaveTable(ref sb, end, iEnemyBoneCount, end ? sRight.Second : sLeft.First);
                    _lHand.Remove(sb);
                    sb.Exchange();
                    _lHand.Remove(sb);
                    return(true);
                }

                _lHand.Add(sbNew);
            }

            //Нельзя сделать ход
            sb.First  = 322;
            sb.Second = 322;
            end       = true;

            _pRight = sRight;
            _pLeft  = sLeft;

            return(false);
        }