/// <summary> /// AgentActivityDatas を初期化します。 /// </summary> public AgentsActivityData(AgentsActivityData agentsActivityData) { Array[0, 0] = new AgentActivityData(agentsActivityData[Team.A, AgentNumber.One]); Array[0, 1] = new AgentActivityData(agentsActivityData[Team.A, AgentNumber.Two]); Array[1, 0] = new AgentActivityData(agentsActivityData[Team.B, AgentNumber.One]); Array[1, 1] = new AgentActivityData(agentsActivityData[Team.B, AgentNumber.Two]); }
/// <summary> /// エージェントを動かしたときに、状態がどう変化するか計算します。 /// </summary> /// <param name="action">どうエージェントが動くか指定します。</param> /// <returns>エージェントを動かしたときの計算データが返ってきます。</returns> public Calc Simulate(AgentsActivityData action) { var c = new Calc(this); c.MoveAgent(new AgentsActivityData(action)); return(c); }
/// <summary> /// Form1内でキーを押したときに実行されます。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void KeyDown(object sender, KeyEventArgs e) { e.SuppressKeyPress = true; ClickField.PushKey(e.KeyCode); AgentsActivityData = ClickField.AgentsActivityData; Showing(); }
/// <summary> /// 指定したところにエージェントが移動します。 /// </summary> /// <param name="team">移動させるチーム</param> /// <param name="agent">移動させるエージェント</param> /// <param name="agentActivityData"></param> public void MoveAgent(Team team, AgentNumber agent, AgentActivityData agentActivityData) { var agentActivityDatas = new AgentsActivityData(AgentStatusCode.RequestNotToDoAnything); agentActivityDatas[team, agent] = agentActivityData; MoveAgent(agentActivityDatas); }
/// <summary> /// クリックしたときに反応します。 /// </summary> /// <returns></returns> public void Click() { var coordinate = CursorPosition(PictureBox); var agentsActivityData = new AgentsActivityData(); try { foreach (var agent in Calc.Agents) { // エージェントをクリックしたとき if (coordinate == agent.Position) { foreach (var neighbor_agent in Calc.Agents) { // もし、エージェントをクリックした場所の隣に、エージェントがいたとき、 if (neighbor_agent.Position.ChebyshevDistance(coordinate) == 1) { DialogResult result = MessageBox.Show("選択するエージェントを" + agent.Name + "に変更しますか?(いいえを押した場合は、" + neighbor_agent.Name + "が" + agent.Name + "のところに移動します。)", "質問", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); switch (result) { case DialogResult.Yes: ClickedAgent = agent; AgentsActivityData[agent.Team, agent.AgentNumber].AgentStatusData = AgentStatusCode.RequestNotToDoAnything; AgentsActivityData[agent.Team, agent.AgentNumber].Destination = coordinate; break; case DialogResult.No: MakeRequest(neighbor_agent, coordinate); break; } return; } } // エージェントをクリックした場所の隣に、エージェントがいないときは、無条件でクリックしたエージェントを選択したエージェントにする。 ClickedAgent = agent; AgentsActivityData[agent.Team, agent.AgentNumber].AgentStatusData = AgentStatusCode.RequestNotToDoAnything; AgentsActivityData[agent.Team, agent.AgentNumber].Destination = coordinate; return; } } foreach (var agent in Calc.Agents) { if (ClickedAgent == agent && coordinate.ChebyshevDistance(agent.Position) == 1) { MakeRequest(agent, coordinate); return; } else if (coordinate.ChebyshevDistance(agent.Position) == 1 && coordinate.ChebyshevDistance(ClickedAgent.Position) != 1) { MakeRequest(agent, coordinate); return; } } } catch (Exception) { MessageBox.Show("フィールドの外です。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// 指定したところにエージェントが移動します。 /// </summary> /// <param name="team">移動させるチーム</param> /// <param name="agentActivityData"></param> public void MoveAgent(Team team, AgentActivityData[] agentActivityData) { var agentActivityDatas = new AgentsActivityData(AgentStatusCode.RequestNotToDoAnything); foreach (AgentNumber agent in Enum.GetValues(typeof(AgentNumber))) { agentActivityDatas[team, agent] = agentActivityData[(int)agent]; } MoveAgent(agentActivityDatas); }
/// <summary> /// 指定したところにエージェントが移動します。 /// </summary> /// <param name="agentsActivityData"></param> public void MoveAgent(AgentsActivityData agentsActivityData) { if (Turn < MaxTurn) { // Undoしたときに // FieldHistory.Count != Turn // になる // TurnEndしたときにやり直す前の未来を消す if (History.Count - 1 != Turn) { History.RemoveRange(Turn + 1, History.Count - 1 - Turn); } // 不正な動きをしていないかチェック CheckAgentActivityData(agentsActivityData); // ターンエンドの処理 TurnEnd(); // ログを取る foreach (Team team in Enum.GetValues(typeof(Team))) { foreach (AgentNumber agent in Enum.GetValues(typeof(AgentNumber))) { History[Turn - 1].AgentsActivityData[team, agent].AgentStatusData = agentsActivityData[team, agent].AgentStatusData; History[Turn - 1].AgentsActivityData[team, agent].Destination = agentsActivityData[team, agent].Destination; } } foreach (Team team in Enum.GetValues(typeof(Team))) { foreach (AgentNumber agent in Enum.GetValues(typeof(AgentNumber))) { switch (agentsActivityData[team, agent].AgentStatusData) { case AgentStatusCode.SucceededInMoving: Agents[team, agent].Position = agentsActivityData[team, agent].Destination; PutTile(team: team, agent: agent); break; case AgentStatusCode.SucceededInRemovingOurTile: RemoveTile(agentsActivityData[team, agent].Destination); break; case AgentStatusCode.SucceededInRemovingOpponentTile: RemoveTile(agentsActivityData[team, agent].Destination); break; default: break; } agentsActivityData[team, agent].ToSuccess(); } } CheckEnclosedArea(); } }
/// <summary> /// TurnDataを初期化します。 /// </summary> public TurnData(TurnData turnData) { Agents = new Agents(turnData.Agents); AgentsActivityData = new AgentsActivityData(turnData.AgentsActivityData); Field = new Field(turnData.Field.Width, turnData.Field.Height); for (int x = 0; x < Field.Width; x++) { for (int y = 0; y < Field.Height; y++) { Field[x, y] = new Cell(turnData.Field[x, y]); } } }
/// <summary> /// XML化するために宣言します /// </summary> /// <param name="xmlTurnData">対象のXmlTurnData</param> public TurnData(XmlTurnData xmlTurnData) { Agents = new Agents(); for (int i = 0; i < 4; i++) { Agents[(Team)(i / 2), (AgentNumber)(i % 2)] = xmlTurnData.Agents[i]; } AgentsActivityData = xmlTurnData.AgentActivityDatas; Field = new Field(xmlTurnData.Width, xmlTurnData.Height); for (int x = 0; x < xmlTurnData.Width; x++) { for (int y = 0; y < xmlTurnData.Height; y++) { Field[x, y] = new Cell(xmlTurnData.Field[y * xmlTurnData.Width + x]); } } }
/// <summary> /// XmlTurnData を指定します。 /// </summary> /// <param name="turnData">対象のターンデータ</param> public XmlTurnData(TurnData turnData) { Agents = new Agent[4]; for (int i = 0; i < 4; i++) { Agents[i] = turnData.Agents[(Team)(i / 2), (AgentNumber)(i % 2)]; } AgentActivityDatas = turnData.AgentsActivityData; Height = turnData.Field.Height; Width = turnData.Field.Width; var max = Height * Width; Field = new XmlCell[max]; for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { Field[y * Width + x] = new XmlCell(turnData.Field[x, y]); } } }
public static void CheckCollision(this AgentsActivityData agentActivityData) { foreach (Team team in Enum.GetValues(typeof(Team))) { foreach (AgentNumber agent in Enum.GetValues(typeof(AgentNumber))) { var item = agentActivityData[team, agent]; if (item.AgentStatusData.IsRequest()) { foreach (Team otherteam in Enum.GetValues(typeof(Team))) { foreach (AgentNumber otheragent in Enum.GetValues(typeof(AgentNumber))) { if (team == otherteam && agent == otheragent) { continue; } var otheritem = agentActivityData[otherteam, otheragent]; if (item.Destination == otheritem.Destination) { if (team == otherteam) { item.ToFailBySelfCollision(); otheritem.ToFailBySelfCollision(); } else { item.ToFailByCollisionWithEachOther(); otheritem.ToFailByCollisionWithEachOther(); } } } } } } } }
/// <summary> /// 初期化します /// </summary> /// <param name="field">フィールドを表します</param> /// <param name="agents">エージェントたちを表します</param> public TurnData(Field field, Agents agents) { Field = field; Agents = agents; AgentsActivityData = new AgentsActivityData(); }
/// <summary> /// 初期化します /// </summary> /// <param name="field">フィールドを表します</param> /// <param name="agents">エージェントたちを表します</param> /// <param name="agentActivityDatas">エージェントの行動データを表します</param> public TurnData(Field field, Agents agents, AgentsActivityData agentActivityDatas) { Field = field; Agents = agents; AgentsActivityData = agentActivityDatas; }
private Task Run(CancellationToken cancellationToken) { var log = new Logger(new RichTextBox()); var tasks = new List <Task>(); var random = new Random(); return(Task.Run(() => { var id = FieldGenerator.GetRandomID(random.Next()); var field_generator = new FieldGenerator(id); var field = field_generator.Generate(); var agents = new Agents(); var coordinates = field_generator.AgentPositionGenerate(field); var bot = new dynamic[2]; if (Bot[(int)Team.A].AssemblyName.Name != "Human") { Assembly m = Assembly.LoadFrom(Bot[(int)Team.A].Path); MatchCollection mc = Regex.Matches(Bot[(int)Team.A].Path, @"^[A-Z]:\\(.*\\)+(?<file>.*).dll$"); foreach (Match match in mc) { bot[(int)Team.A] = Activator.CreateInstance(m.GetType("nitkagoshima_sysken.Procon29." + match.Groups["file"].Value + "." + match.Groups["file"].Value)); } } if (Bot[(int)Team.B].AssemblyName.Name != "Human") { Assembly m = Assembly.LoadFrom(Bot[(int)Team.B].Path); MatchCollection mc = Regex.Matches(Bot[(int)Team.B].Path, @"^[A-Z]:\\(.*\\)+(?<file>.*).dll$"); foreach (Match match in mc) { bot[(int)Team.B] = Activator.CreateInstance(m.GetType("nitkagoshima_sysken.Procon29." + match.Groups["file"].Value + "." + match.Groups["file"].Value)); } } agents[Team.A, AgentNumber.One].Position = coordinates[0]; agents[Team.A, AgentNumber.Two].Position = coordinates[1]; agents[Team.B, AgentNumber.One].Position = new Coordinate(MainForm.ComplementEnemysPosition(field, coordinates[0])); agents[Team.B, AgentNumber.Two].Position = new Coordinate(MainForm.ComplementEnemysPosition(field, coordinates[1])); var calc = new Calc(MainForm.MaxTurn, field, agents); Invoke( new add_delegate(Add), id, calc.Turn, calc.Field.Sum(cell => cell.Point), calc.Field.TotalPoint(Team.A), calc.Field.TotalPoint(Team.B), ((double)calc.Field.Count(cell => cell.IsTileOn[Team.A]) / calc.Field.Count()).ToString("P"), ((double)calc.Field.Count(cell => cell.IsTileOn[Team.B]) / calc.Field.Count()).ToString("P")); while (calc.Turn < calc.MaxTurn) { var action = new AgentsActivityData(); if (bot[0] != null) { dynamic answer; lock (bot[0]) { bot[0].OurTeam = Team.A; bot[0].Log = log; bot[0].Question(new Calc(calc)); answer = bot[0].Answer(); } action[Team.A, AgentNumber.One] = answer[0]; action[Team.A, AgentNumber.Two] = answer[1]; } if (bot[1] != null) { dynamic answer; lock (bot[1]) { bot[1].OurTeam = Team.B; bot[1].Log = log; bot[1].Question(new Calc(calc)); answer = bot[1].Answer(); } action[Team.B, AgentNumber.One] = answer[0]; action[Team.B, AgentNumber.Two] = answer[1]; } if (cancellationToken.IsCancellationRequested) { Console.WriteLine("Canceled!"); return "Canceled"; } calc.MoveAgent(action); Invoke( new edit_delegate(Edit), id, calc.Turn, calc.Field.Sum(cell => cell.Point), calc.Field.TotalPoint(Team.A), calc.Field.TotalPoint(Team.B), ((double)calc.Field.Count(cell => cell.IsTileOn[Team.A]) / calc.Field.Count()).ToString("P"), ((double)calc.Field.Count(cell => cell.IsTileOn[Team.B]) / calc.Field.Count()).ToString("P")); } Invoke(new end_delegate(End), id); return "Succeed"; })); }
void CheckAgentActivityData(AgentsActivityData agentsActivityData) { foreach (Team team in Enum.GetValues(typeof(Team))) { foreach (AgentNumber agent in Enum.GetValues(typeof(AgentNumber))) { var item = agentsActivityData[team, agent]; // 何もしないのは、無条件で成功する(1) // SucceededNotToDoAnything if (item.AgentStatusData == AgentStatusCode.RequestNotToDoAnything) { item.AgentStatusData = AgentStatusCode.SucceededNotToDoAnything; continue; } // リクエストの禁止や、何も命令がないときは無条件でスキップ(2) if (item.AgentStatusData == AgentStatusCode.NotDoneAnything || item.AgentStatusData == AgentStatusCode.RequestForbidden) { continue; } // 自分自身の衝突をチェック(2) // YouHadCollisionsWithYourselfAndYouFailedToMoveBecauseYouAreThereAlready // YouHadCollisionsWithYourselfAndYouFailedToRemoveTilesFromYourTeam; if (item.AgentStatusData != AgentStatusCode.RequestRemovementOpponentTile && item.Destination == Agents[team, agent].Position) { item.AgentStatusData = item.AgentStatusData.ToYouHadCollisionsWithYourselfAndYouFailed(); continue; } // 目標部が自分から遠い場所にないかチェック(3) // FailedInMovingByBeingNotChebyshevNeighborhood // FailedInRemovingOurTileByBeingNotChebyshevNeighborhood // FailedInRemovingOpponentTileByBeingNotChebyshevNeighborhood if (item.Destination.ChebyshevDistance(Agents[team, agent].Position) != 1) { item.AgentStatusData = item.AgentStatusData.ToFailedByBeingNotMooreNeighborhood(); continue; } // 目標部がフィールドの外にないかチェック(3) // FailedInMovingByTryingToGoOutOfTheFieldWithEachOther // FailedInRemovingOurTileByTryingToGoOutOfTheField // FailedInRemovingOpponentTileByTryingToGoOutOfTheField if (!Field.CellExist(item.Destination)) { item.AgentStatusData = item.AgentStatusData.ToFailedInMovingByTryingToGoOutOfTheField(); continue; } // 剥がそうとしていたタイルが存在していないかチェック(2) // FailedInRemovingOurTileByDoingTileNotExist // FailedInRemovingOpponentTileByDoingTileNotExist if (item.AgentStatusData == AgentStatusCode.RequestRemovementOurTile && Field[item.Destination.X, item.Destination.Y].IsTileOn[team] == false) { item.AgentStatusData = AgentStatusCode.FailedInRemovingOurTileByDoingTileNotExist; continue; } if (item.AgentStatusData == AgentStatusCode.RequestRemovementOpponentTile && Field[item.Destination.X, item.Destination.Y].IsTileOn[team.Opponent()] == false) { item.AgentStatusData = AgentStatusCode.FailedInRemovingOpponentTileByDoingTileNotExist; continue; } // 移動先に相手のタイルが置いてないかチェック(1) // FailedInMovingByTryingItWithoutRemovingTheOpponentTile if (item.AgentStatusData == AgentStatusCode.RequestMovement && Field[item.Destination].IsTileOn[team.Opponent()]) { item.AgentStatusData = AgentStatusCode.FailedInMovingByTryingItWithoutRemovingTheOpponentTile; continue; } // 動かないエージェントに衝突していないかチェック(4) // FailedInMovingByCollisionWithTheLazyOurTeam // FailedInRemovingOurTileWithTheLazyOurTeam // FailedInMovingByCollisionWithTheLazyOpponent // FailedInRemovingOpponentTileWithTheLazyOpponent foreach (Team otherteam in Enum.GetValues(typeof(Team))) { foreach (AgentNumber otheragent in Enum.GetValues(typeof(AgentNumber))) { if (team == otherteam && agent == otheragent) { continue; } var otheritem = agentsActivityData[otherteam, otheragent]; var otherposition = Agents[otherteam, otheragent].Position; if (otheritem.AgentStatusData != AgentStatusCode.RequestMovement && item.Destination == otherposition) { if (team == otherteam) { item.ToFailByCollisionWithTheLazyOurTeam(); } else { item.ToFailByCollisionWithTheLazyOpponent(); } } } } } } // 自分または相手のチームと衝突していないかチェック(6) // FailedInMovingBySelfCollision; // FailedInRemovingOurTileBySelfCollision; // FailedInRemovingOpponentTileBySelfCollision; // FailedInMovingByCollisionWithEachOther; // FailedInRemovingOurTileByCollisionWithEachOther; // FailedInRemovingOpponentTileByCollisionWithEachOther; agentsActivityData.CheckCollision(); // 移動先のエージェントがコリジョンを起こし、 // 自分もそのコリジョンに巻き込まれたかチェック(3) // FailedInMovingByInvolvedInOtherCollisions // FailedInRemovingOpponentTileByInvolvedInOtherCollisions // FailedInRemovingOurTileByInvolvedInOtherCollisions foreach (Team team in Enum.GetValues(typeof(Team))) { foreach (AgentNumber agent in Enum.GetValues(typeof(AgentNumber))) { var item = agentsActivityData[team, agent]; foreach (Team otherteam in Enum.GetValues(typeof(Team))) { foreach (AgentNumber otheragent in Enum.GetValues(typeof(AgentNumber))) { if (team == otherteam && agent == otheragent) { continue; } var otheritem = agentsActivityData[otherteam, otheragent]; var otherposition = Agents[otherteam, otheragent].Position; if ((otheritem.AgentStatusData == AgentStatusCode.RequestNotToDoAnything || otheritem.AgentStatusData == AgentStatusCode.NotDoneAnything || otheritem.AgentStatusData.IsFailed()) && item.Destination == otherposition) { switch (item.AgentStatusData) { case AgentStatusCode.RequestMovement: item.AgentStatusData = AgentStatusCode.FailedInMovingByInvolvedInOtherCollisions; break; case AgentStatusCode.RequestRemovementOurTile: item.AgentStatusData = AgentStatusCode.FailedInRemovingOpponentTileByInvolvedInOtherCollisions; break; case AgentStatusCode.RequestRemovementOpponentTile: item.AgentStatusData = AgentStatusCode.FailedInRemovingOurTileByInvolvedInOtherCollisions; break; default: break; } } } } } } // 全チェック後に残ったリクエストは、成功したとみなす(3) foreach (var item in agentsActivityData) { item.ToSuccess(); } }
public void ClickShow() { ClickField.Click(); AgentsActivityData = ClickField.AgentsActivityData; }