/// <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); }
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)); }