/// <summary>
                /// エージェントを動かしたときに、状態がどう変化するか計算します。
                /// </summary>
                /// <param name="action">どうエージェントが動くか指定します。</param>
                /// <returns>エージェントを動かしたときの計算データが返ってきます。</returns>
                public Calc Simulate(Team team, AgentNumber agentNumber, AgentActivityData action)
                {
                    var c = new Calc(Calc);

                    c.MoveAgent(team, agentNumber, action.DeepClone());
                    return(c);
                }
예제 #2
0
        public override AgentActivityData[] Answer()
        {
            isOdd    = IsOdd();
            agentOne = Calc.Agents[OurTeam, AgentNumber.One];
            agentTwo = Calc.Agents[OurTeam, AgentNumber.Two];
            var result = new AgentActivityData[2];

            result = BestHand(Calc, 2).AgentActivityData;


            return(result);
        }
예제 #3
0
        public override AgentActivityData[] Answer()
        {
            var list = new List <ReturnStruct>();

            foreach (Arrow arrow1 in Enum.GetValues(typeof(Arrow)))
            {
                foreach (Arrow arrow2 in Enum.GetValues(typeof(Arrow)))
                {
                    var position = new Coordinate[]
                    {
                        Calc.Agents[OurTeam, AgentNumber.One].Position + arrow1,
                        Calc.Agents[OurTeam, AgentNumber.Two].Position + arrow2,
                    };
                    if (position[(int)AgentNumber.One] == position[(int)AgentNumber.Two] ||
                        !Calc.Field.CellExist(position[(int)AgentNumber.One]) ||
                        !Calc.Field.CellExist(position[(int)AgentNumber.Two]))
                    {
                        continue;
                    }
                    foreach (var asc1 in AgentStatusCodes)
                    {
                        foreach (var asc2 in AgentStatusCodes)
                        {
                            var action = new AgentActivityData[] {
                                new AgentActivityData(asc1, position[(int)AgentNumber.One]),
                                new AgentActivityData(asc2, position[(int)AgentNumber.Two]),
                            };
                            var next_calc = Simulate(OurTeam, action);
                            if (next_calc.History[Calc.Turn].AgentsActivityData[OurTeam, AgentNumber.One].AgentStatusData.IsFailed() ||
                                next_calc.History[Calc.Turn].AgentsActivityData[OurTeam, AgentNumber.One].AgentStatusData.IsFailed())
                            {
                                continue;
                            }
                            list.Add(
                                new ReturnStruct
                            {
                                Evaluation =
                                    EvaluationFunction(position[(int)AgentNumber.One]) +
                                    next_calc.History[Calc.Turn + 1].Field.TotalPoint(OurTeam) - next_calc.History[Calc.Turn + 1].Field.TotalPoint(OurTeam.Opponent())
                                    - (Calc.Field.TotalPoint(OurTeam) - Calc.Field.TotalPoint(OurTeam.Opponent())),
                                ActivityData = action,
                            });
                        }
                    }
                }
            }
            return(list.Max().ActivityData);
        }
        public override AgentActivityData[] Answer()
        {
            var        result            = new AgentActivityData[2];
            var        maxpoint          = double.MinValue;
            var        rate              = 1.0;
            var        agentActivityData = new AgentActivityData[2];
            Calc       calc;
            Coordinate destinationOne;
            Coordinate destinationTwo;
            double     nowpoint;

            foreach (Arrow arrowOne in Enum.GetValues(typeof(Arrow)))
            {
                destinationOne = Calc.Agents[OurTeam, AgentNumber.One].Position + arrowOne;
                if (!Calc.Field.CellExist(destinationOne))
                {
                    continue;
                }

                foreach (Arrow arrowTwo in Enum.GetValues(typeof(Arrow)))
                {
                    destinationTwo = Calc.Agents[OurTeam, AgentNumber.Two].Position + arrowTwo;
                    if (!Calc.Field.CellExist(destinationTwo))
                    {
                        continue;
                    }
                    if (destinationOne == destinationTwo)
                    {
                        continue;
                    }

                    //Setting AgentActivityData
                    //AgentNumber.One
                    rate = 1.0;
                    agentActivityData[(int)AgentNumber.One] = Calc.Field[destinationOne].IsTileOn[OurTeam.Opponent()]?
                                                              new AgentActivityData(AgentStatusCode.RequestRemovementOpponentTile, destinationOne):
                                                              new AgentActivityData(AgentStatusCode.RequestMovement, destinationOne);
                    rate *= 0.1 / (Math.Abs(destinationOne.X + 1 - Calc.Field.Width / 2.0) + 1) + 1.0;
                    rate *= 0.1 / (Math.Abs(destinationOne.Y + 1 - Calc.Field.Height / 2.0) + 1) + 1.0;

                    //AgentNumber.Two
                    agentActivityData[(int)AgentNumber.Two] = Calc.Field[destinationTwo].IsTileOn[OurTeam.Opponent()]?
                                                              new AgentActivityData(AgentStatusCode.RequestRemovementOpponentTile, destinationTwo):
                                                              new AgentActivityData(AgentStatusCode.RequestMovement, destinationTwo);
                    rate *= 0.1 / (Math.Abs(destinationTwo.X + 1 - Calc.Field.Width / 2.0) + 1) + 1.0;
                    rate *= 0.1 / (Math.Abs(destinationTwo.Y + 1 - Calc.Field.Height / 2.0) + 1) + 1.0;

                    //Simulate
                    calc = Calc.Simulate(OurTeam, agentActivityData);

                    //AgentStatusCode transform RequestCode
                    foreach (var item in agentActivityData)
                    {
                        item.AgentStatusData.ToRequest();
                    }
                    nowpoint = rate * (
                        ((double)calc.Field.TotalPoint(OurTeam) - (double)Calc.Field.TotalPoint(OurTeam))
                        - ((double)calc.Field.TotalPoint(OurTeam.Opponent()) - (double)Calc.Field.TotalPoint(OurTeam.Opponent())));
                    if (maxpoint < nowpoint)
                    {
                        maxpoint = nowpoint;
                        result   = agentActivityData.DeepClone();
                    }
                }
            }
            return(result);
        }
예제 #5
0
        public override AgentActivityData[] Answer()
        {
            var result = new AgentActivityData[2];
            //一人目のエージェントがどの方向に行くかを保存する
            var agent1dir = Arrow.Up;
            //二人目のエージェントがどの方向に行くかを保存する
            var agent2dir = Arrow.Up;
            //エージェント1が理想的にとれる最高値
            var agent1pmax = int.MinValue;
            //エージェント2が理想的にとれる最高値
            var        agent2pmax = int.MinValue;
            Coordinate coodinate;
            var        sum      = 0;
            var        count    = 0;
            var        nowpoint = 0;
            Coordinate pastposition;
            var        enowpoint = 0;
            Calc       calc;

            int[,] prob = new int[, ] {
                { 3, 2, 2, 4, 8, 4, 2, 2 },
                { 2, 1, 2, 3, 4, 8, 4, 3 },
                { 2, 2, 3, 2, 2, 4, 8, 4 },
                { 4, 3, 2, 1, 2, 3, 4, 8 },
                { 8, 4, 2, 2, 3, 2, 2, 4 },
                { 4, 8, 4, 3, 2, 1, 2, 3 },
                { 2, 4, 8, 4, 2, 2, 3, 2 },
                { 2, 3, 4, 8, 4, 3, 2, 1 }
            };
            coodinate    = Calc.Agents[OurTeam, AgentNumber.One].Position;
            pastposition = null;
            foreach (Arrow arrow in Enum.GetValues(typeof(Arrow)))
            {
                sum      = 0;
                count    = 0;
                nowpoint = Calc.TotalPoint(OurTeam);
                calc     = Simulate(OurTeam, AgentNumber.One, new AgentActivityData(AgentStatusCode.RequestMovement, coodinate + arrow));
                foreach (Arrow arrow2 in Enum.GetValues(typeof(Arrow)))
                {
                    try
                    {
                        calc = calc.Simulate(OurTeam, AgentNumber.One, new AgentActivityData(AgentStatusCode.RequestMovement, coodinate + arrow + arrow2));
                        if (Calc.Field[coodinate + arrow].IsTileOn[OurTeam.Opponent()])
                        {
                            sum += Calc.Field[coodinate + arrow].Point + 27 * (enowpoint - calc.TotalPoint(OurTeam.Opponent()));
                        }
                        if (Calc.Field[coodinate + arrow].IsTileOn[OurTeam.Opponent()])
                        {
                            sum += 0;
                        }
                        else
                        {
                            sum += prob[(int)arrow, (int)arrow2] * (calc.TotalPoint(OurTeam) - nowpoint);
                        }
                    } catch (Exception e)
                    {
                        count++;
                        continue;
                    }
                }
                if ((agent1pmax < sum) && (count != 8))
                {
                    agent1pmax = sum;
                    agent1dir  = arrow;
                }
                if (pastposition == coodinate)
                {
                    agent1dir++;
                }
                pastposition = coodinate;
            }
            if (Calc.Field[Calc.Agents[OurTeam, AgentNumber.One].Position + agent1dir].IsTileOn[OurTeam.Opponent()])
            {
                result[(int)AgentNumber.One] = new AgentActivityData(AgentStatusCode.RequestRemovementOpponentTile, Calc.Agents[OurTeam, AgentNumber.One].Position + agent1dir);
            }
            result[(int)AgentNumber.One] = new AgentActivityData(AgentStatusCode.RequestMovement, Calc.Agents[OurTeam, AgentNumber.One].Position + agent1dir);

            coodinate    = Calc.Agents[OurTeam, AgentNumber.Two].Position;
            pastposition = null;
            foreach (Arrow arrow in Enum.GetValues(typeof(Arrow)))
            {
                sum      = 0;
                count    = 0;
                nowpoint = Calc.TotalPoint(OurTeam);
                calc     = Simulate(OurTeam, AgentNumber.Two, new AgentActivityData(AgentStatusCode.RequestMovement, coodinate + arrow));
                foreach (Arrow arrow2 in Enum.GetValues(typeof(Arrow)))
                {
                    try
                    {
                        calc = calc.Simulate(OurTeam, AgentNumber.Two, new AgentActivityData(AgentStatusCode.RequestMovement, coodinate + arrow + arrow2));
                        if (Calc.Field[coodinate + arrow].IsTileOn[OurTeam.Opponent()])
                        {
                            sum += Calc.Field[coodinate + arrow].Point + 27 * (enowpoint - calc.TotalPoint(OurTeam.Opponent()));
                        }
                        if (Calc.Field[coodinate + arrow].IsTileOn[OurTeam.Opponent()])
                        {
                            sum += 0;
                        }
                        else
                        {
                            sum += prob[(int)arrow, (int)arrow2] * (calc.TotalPoint(OurTeam) - nowpoint);
                        }
                    }
                    catch (Exception e)
                    {
                        count++;
                        continue;
                    }
                }

                if ((agent2pmax < sum) && (count != 8))
                {
                    agent2pmax = sum;
                    agent2dir  = arrow;
                }
                if (pastposition == coodinate)
                {
                    agent1dir++;
                }
                pastposition = coodinate;
            }
            if (Calc.Field[Calc.Agents[OurTeam, AgentNumber.Two].Position + agent2dir].IsTileOn[OurTeam.Opponent()])
            {
                result[(int)AgentNumber.Two] = new AgentActivityData(AgentStatusCode.RequestRemovementOpponentTile, Calc.Agents[OurTeam, AgentNumber.Two].Position + agent2dir);
            }
            result[(int)AgentNumber.Two] = new AgentActivityData(AgentStatusCode.RequestMovement, Calc.Agents[OurTeam, AgentNumber.Two].Position + agent2dir);
            return(result);
        }
예제 #6
0
        private ReturnStruct BestHand(Calc calc, int depth)
        {
            var maxpoint          = int.MinValue;
            var agentActivityData = new AgentActivityData[2];
            var result            = new AgentActivityData[2];

            foreach (Arrow arrowOne in Enum.GetValues(typeof(Arrow)))
            {
                var destinationOne = calc.Agents[OurTeam, AgentNumber.One].Position + arrowOne;
                if (!calc.Field.CellExist(destinationOne))
                {
                    continue;
                }

                foreach (Arrow arrowTwo in Enum.GetValues(typeof(Arrow)))
                {
                    var destinationTwo = calc.Agents[OurTeam, AgentNumber.Two].Position + arrowTwo;
                    if (!calc.Field.CellExist(destinationTwo))
                    {
                        continue;
                    }
                    if (destinationOne == destinationTwo)
                    {
                        continue;
                    }
                    if ((destinationOne.X + destinationOne.Y) % 2 != 0 == isOdd)
                    {
                        agentActivityData[(int)AgentNumber.One] = MoveOrRemoveTile(destinationOne);
                    }
                    else
                    {
                        agentActivityData[(int)AgentNumber.One] = RemoveTile(destinationOne);
                        if (agentActivityData[(int)AgentNumber.One].AgentStatusData == AgentStatusCode.RequestNotToDoAnything)
                        {
                            continue;
                        }
                    }

                    if (((destinationTwo.X + destinationTwo.Y) % 2 != 0) == isOdd)
                    {
                        agentActivityData[(int)AgentNumber.Two] = MoveOrRemoveTile(destinationTwo);
                    }
                    else
                    {
                        agentActivityData[(int)AgentNumber.Two] = RemoveTile(destinationTwo);
                        if (agentActivityData[(int)AgentNumber.Two].AgentStatusData == AgentStatusCode.RequestNotToDoAnything)
                        {
                            continue;
                        }
                    }
                    var c = calc.Simulate(OurTeam, agentActivityData);
                    foreach (var item in agentActivityData)
                    {
                        item.AgentStatusData.ToRequest();
                    }
                    if (depth <= 1)
                    {
                        if (maxpoint < (c.Field.TotalPoint(OurTeam) - c.Field.TotalPoint(OurTeam.Opponent())))
                        {
                            maxpoint = c.Field.TotalPoint(OurTeam) - c.Field.TotalPoint(OurTeam.Opponent());
                            result   = agentActivityData.DeepClone();
                        }
                    }
                    else
                    {
                        var bestHand = BestHand(c, depth - 1);
                        if (maxpoint < bestHand.point)
                        {
                            maxpoint = bestHand.point;
                            result   = agentActivityData.DeepClone();
                        }
                    }
                }
            }
            return(new ReturnStruct(maxpoint, result));
        }
예제 #7
0
        public override AgentActivityData[] Answer()
        {
            var AgentActivityData = new AgentActivityData[2]
            {
                new AgentActivityData(AgentStatusCode.RequestNotToDoAnything),
                new AgentActivityData(AgentStatusCode.RequestNotToDoAnything),
            };
            int maxpoint = int.MinValue; // 最大値

            foreach (Arrow arrow1 in Enum.GetValues(typeof(Arrow)))
            {
                foreach (Arrow arrow2 in Enum.GetValues(typeof(Arrow)))
                {
                    if (Calc.Field.CellExist(Calc.Agents[OurTeam, AgentNumber.One].Position + arrow1) &&
                        Calc.Field.CellExist(Calc.Agents[OurTeam, AgentNumber.Two].Position + arrow2))
                    {
                        var test = new AgentActivityData[2]
                        {
                            new AgentActivityData()
                            {
                                AgentStatusData = MoveOrRemove(Calc.Agents[OurTeam, AgentNumber.One], arrow1),
                                Destination     = Calc.Agents[OurTeam, AgentNumber.One].Position + arrow1
                            },
                            new AgentActivityData()
                            {
                                AgentStatusData = MoveOrRemove(Calc.Agents[OurTeam, AgentNumber.Two], arrow2),
                                Destination     = Calc.Agents[OurTeam, AgentNumber.Two].Position + arrow2
                            },
                        };
                        var c     = Simulate(OurTeam, test);
                        var point = c.Field.TotalPoint(OurTeam) - c.Field.TotalPoint(OurTeam.Opponent());
                        if (maxpoint < point)
                        {
                            var pastcalc = Calc.History[(Calc.Turn - 1 > 0) ? Calc.Turn - 1 : 0];
                            if ((pastcalc.AgentsActivityData[OurTeam, AgentNumber.One].AgentStatusData != AgentStatusCode.NotDoneAnything &&
                                 pastcalc.AgentsActivityData[OurTeam, AgentNumber.One].AgentStatusData.ToRequest() != test[0].AgentStatusData) ||
                                pastcalc.AgentsActivityData[OurTeam, AgentNumber.One].Destination != test[0].Destination ||
                                (pastcalc.AgentsActivityData[OurTeam, AgentNumber.Two].AgentStatusData != AgentStatusCode.NotDoneAnything &&
                                 pastcalc.AgentsActivityData[OurTeam, AgentNumber.Two].AgentStatusData.ToRequest() != test[1].AgentStatusData) ||
                                pastcalc.AgentsActivityData[OurTeam, AgentNumber.Two].Destination != test[1].Destination)
                            {
                                maxpoint = point;
                            }
                            if ((pastcalc.AgentsActivityData[OurTeam, AgentNumber.One].AgentStatusData != AgentStatusCode.NotDoneAnything &&
                                 pastcalc.AgentsActivityData[OurTeam, AgentNumber.One].AgentStatusData.ToRequest() != test[0].AgentStatusData) ||
                                pastcalc.AgentsActivityData[OurTeam, AgentNumber.One].Destination != test[0].Destination)
                            {
                                AgentActivityData[0].AgentStatusData = test[0].AgentStatusData;
                                AgentActivityData[0].Destination     = test[0].Destination;
                            }
                            else
                            {
                                Log.WriteLine("error yesterday crash one");
                            }
                            if ((pastcalc.AgentsActivityData[OurTeam, AgentNumber.Two].AgentStatusData != AgentStatusCode.NotDoneAnything &&
                                 pastcalc.AgentsActivityData[OurTeam, AgentNumber.Two].AgentStatusData.ToRequest() != test[1].AgentStatusData) ||
                                pastcalc.AgentsActivityData[OurTeam, AgentNumber.Two].Destination != test[1].Destination)
                            {
                                AgentActivityData[1].AgentStatusData = test[1].AgentStatusData;
                                AgentActivityData[1].Destination     = test[1].Destination;
                            }
                            else
                            {
                                Log.WriteLine("error yesterday crash two");
                            }
                        }
                    }
                }
            }
            //System.Random r = new System.Random(1000);


            return(AgentActivityData);
        }
예제 #8
0
                /// <summary>
                /// あなたが、どこにエージェントを行かせるかを、
                /// この関数に書きます。
                /// </summary>
                /// <returns>どこにエージェントに行かせるか</returns>
                public override AgentActivityData[] Answer()
                {
                    var result = new AgentActivityData[2];

                    // 一人目のエージェントの最高得点を保存するために使う変数
                    var agnt1maxp = -16;
                    // 二人目のエージェントの最高得点を保存するために使う変数
                    var agnt2maxp = -16;
                    // 一人目のエージェントがどこに行くかを保存するために使う変数
                    Coordinate agnt1pos = new Coordinate();
                    // 二人目のエージェントがどこに行くかを保存するために使う変数
                    Coordinate agnt2pos = new Coordinate();

                    /*
                     * これはクエリ式というもので、
                     * まるで、データベースで使うSQL文のようにデータを扱えるようになっている
                     * var list =
                     * エージェントが行けるマスをリストにする変数をここで宣言している。
                     * from cell in Calc.Field
                     * 《from句》どのデータテーブルからデータを読むか
                     * 今回の場合は、「Calcのフィールドから、マスを一つずつ取り出して、それにcellという名前をつける」
                     * where cell.Coordinate.ChebyshevDistance(Calc.Agents[Team, AgentNumber.One].Position) == 1
                     * 《where句》取り出したいデータに対する条件
                     * 今回の場合は、「取り出したマス(cell)の座標から一人目のエージェントのいる場所までのチェビシェフ距離がちょうど1なら条件に適している」
                     * (つまり、エージェントの隣のマスなら条件に適している)
                     * select cell.Coordinate;
                     * 《select句》条件にヒットしたデータの何を取り出すか
                     * 今回の場合は、条件にヒットしたマス(つまり、エージェントの隣のマス)の座標を取り出して、それをリスト化する
                     *
                     * …つまり、この行では、一人目のエージェントの隣のマスの一覧をリストにしている。
                     * C#のクエリ式についてはネットで調べれば、もっと詳しく載っているので、そちらを参照した方がいい。
                     */
                    var list =
                        from cell in Calc.Field
                        where cell.Coordinate.ChebyshevDistance(Calc.Agents[OurTeam, AgentNumber.One].Position) == 1
                        select cell.Coordinate;

                    // 取り出したリストから一つずつ座標を取り出して、for文のように繰り返し処理を行う。
                    foreach (var coordinate in list)
                    {
                        var trying = new AgentActivityData[2]
                        {
                            // Bot側のチーム、1人目のエージェントがcoordinateに移動する
                            new AgentActivityData(AgentStatusCode.RequestMovement, coordinate),
                            // Bot側のチーム、2人目のエージェントは何もしない
                            new AgentActivityData(AgentStatusCode.RequestNotToDoAnything)
                        };

                        /*
                         * Simulate関数
                         * これはもしもそこへ行ったらどうなるかをシミュレートしてくれる関数です。
                         */
                        var c = Simulate(team: OurTeam, action: trying);

                        // 今までの中で一番、得点が高かったら、得点とその座標を更新する
                        if (agnt1maxp < c.Field.TotalPoint(OurTeam))
                        {
                            agnt1maxp = c.Field.TotalPoint(OurTeam);
                            agnt1pos  = new Coordinate(coordinate);
                        }
                    }
                    // Bot側のチーム、1人目のエージェントがagnt1posに行くことが確定する
                    result[(int)AgentNumber.One] = new AgentActivityData(AgentStatusCode.RequestMovement, agnt1pos);

                    /*
                     * 実は、エージェントの場所から1ターンでいける範囲は、
                     * Arrowを使ってもっと簡単に実装できます。
                     * Arrowはenum型で、
                     * Arrow.Up で 上に行く
                     * Arrow.Rightで 右に行く
                     * とかできます。
                     * foreach (Arrow arrow in Enum.GetValues(typeof(Arrow)))
                     * で、Arrowのすべての要素を一つずつ実行できるので、
                     * エージェントのいるところから、周り1マス分のマスに関して、
                     * すべてシミュレーションできます。
                     */
                    foreach (Arrow arrow in Enum.GetValues(typeof(Arrow)))
                    {
                        var c = Simulate(
                            OurTeam,
                            AgentNumber.Two,
                            new AgentActivityData(AgentStatusCode.RequestMovement, Calc.Agents[OurTeam, AgentNumber.Two].Position + arrow));

                        if (agnt2maxp < c.Field.TotalPoint(OurTeam))
                        {
                            agnt2maxp = c.Field.TotalPoint(OurTeam);
                            agnt2pos  = new Coordinate(Calc.Agents[OurTeam, AgentNumber.Two].Position + arrow);
                        }
                    }
                    result[(int)AgentNumber.Two] = new AgentActivityData(AgentStatusCode.RequestMovement, agnt2pos);
                    return(result);
                }