/// <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);
                }
        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);
        }
예제 #3
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));
        }