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