/// <summary> /// Combinedスタンプから構成される解をOriginalスタンプの解に変換する /// </summary> /// <param name="combined_solution">Combinedスタンプから成る解</param> /// <returns>Originalスタンプから構成される解</returns> public Solution CombinedSolutionToOriginalSolution(Solution combined_solution) { // combined_stampをオリジナルスタンプに分解してtmp_origin_solutionに追加 Solution tmp_origin_solution = new Solution(); { List <Tuple <Stamp, short, short> > combined_answer_list = combined_solution.GetStampAnswerList(); foreach (var combined_answer in combined_answer_list) { CombinedStamp combined_stamp = (CombinedStamp)combined_answer.Item1; List <Tuple <short, short, short> > origin_stamp_config_list = combined_stamp.GetOriginStampConfigList(); short combined_stamp_slide_x = combined_answer.Item2; short combined_stamp_slide_y = combined_answer.Item3; foreach (var origin_stamp_config in origin_stamp_config_list) { short origin_stamp_idx = origin_stamp_config.Item1; short origin_stamp_slide_x = origin_stamp_config.Item2; short origin_stamp_slide_y = origin_stamp_config.Item3; Stamp origin_stamp_object = this.origin_stamp_object_list[origin_stamp_idx]; tmp_origin_solution.AddStampAnswer(origin_stamp_object, (short)(origin_stamp_slide_x + combined_stamp_slide_x), (short)(origin_stamp_slide_y + combined_stamp_slide_y)); } } } // 枠外にはみ出たオリジナルスタンプ以外をorigin_solutionに追加 Solution origin_solution = new Solution(); { List <Tuple <Stamp, short, short> > origin_stamp_answer_list = tmp_origin_solution.GetStampAnswerList(); foreach (var origin_stamp_answer in origin_stamp_answer_list) { Stamp stamp = origin_stamp_answer.Item1; short slide_x = origin_stamp_answer.Item2; short slide_y = origin_stamp_answer.Item3; // x方向チェック if (stamp.GetXSize() + slide_x <= 0 || slide_x >= field.GetXSize()) { continue; } // y方向チェック if (stamp.GetYSize() + slide_y <= 0 || slide_y >= field.GetYSize()) { continue; } origin_solution.AddStampAnswer(stamp, slide_x, slide_y); } } return(origin_solution); }
/// <summary> /// スタンプを追加する。このとき、親クラスのメンバ変数も更新される。 /// ただし、x_sizeとy_sizeは、黒セルの入っているセルのうち最も外側にあるものの値とする。 /// /// e.g.) black_cell_coordinates が次のような場合、x_size=7, x_size=3になる。 /// ...#.... /// .#..#..# /// ...#.... /// ....... /// </summary> /// <param name="origin_stamp">追加するスタンプ</param> /// <param name="slide_x">x方向へのスライド距離</param> /// <param name="slide_y">y方向へのスライド距離</param> public void AddStamp(Instance instance, Stamp stamp, short slide_x, short slide_y) { if (stamp.IsOriginalStamp()) { AddOriginalStamp(stamp, slide_x, slide_y); } else { AddCombinedStamp(instance, (CombinedStamp)stamp, slide_x, slide_y); } }
private void AddCombinedStamp(Instance instance, CombinedStamp combined_stamp, short slide_x, short slide_y) { var origin_stamp_list = instance.GetOriginalStampObjectList(); foreach (var origin_stamp_config in combined_stamp.GetOriginStampConfigList()) { Stamp origin_stamp = origin_stamp_list[origin_stamp_config.Item1]; short origin_x = origin_stamp_config.Item2; short origin_y = origin_stamp_config.Item3; AddOriginalStamp(origin_stamp, (short)(origin_x + slide_x), (short)(origin_y + slide_y)); } }
/// <summary> /// stampを平行移動したのち、myfieldに押す。 /// </summary> /// <param name="stamp">スタンプのオブジェクト</param> /// <param name="parallel_translation_x">x軸方向への平行移動距離</param> /// <param name="parallel_translation_y">y軸方向への平行移動距離</param> public void PressStamp(Stamp stamp, short parallel_translation_x, short parallel_translation_y) { foreach (var cell in stamp.GetBlackCellCoordinate()) { short y = (short)(parallel_translation_y + cell.Item1); short x = (short)(parallel_translation_x + cell.Item2); // スタンプを押す場所が my field の外なら continue if (y < 0 || y >= this.y_size || x < 0 || x >= this.x_size) { continue; } this.my_field[y, x] = !my_field[y, x]; } }
private void AddOriginalStamp(Stamp origin_stamp, short slide_x, short slide_y) { // CombinedStampのメンバ変数の更新 this.origin_stamp_config_list.Add(new Tuple <short, short, short>(origin_stamp.GetOriginStampIndex(), slide_x, slide_y)); // 親クラス(Stamp)のメンバ変数の更新 // black_cell_coordinate_listの更新 List <Tuple <short, short> > add_stamp_black_cell_list = origin_stamp.GetBlackCellCoordinate(); foreach (var black_cell in add_stamp_black_cell_list) { short y = (short)(black_cell.Item1 + slide_y); short x = (short)(black_cell.Item2 + slide_x); Tuple <short, short> reverse_cell = new Tuple <short, short>(y, x); if (this.black_cell_coordinates.Contains(reverse_cell)) { this.black_cell_coordinates.Remove(reverse_cell); } else { this.black_cell_coordinates.Add(reverse_cell); } } // size_y, size_xの更新 short black_cell_max_y = 0; short black_cell_max_x = 0; foreach (var cell in this.black_cell_coordinates) { black_cell_max_y = Math.Max(cell.Item1, black_cell_max_y); black_cell_max_x = Math.Max(cell.Item2, black_cell_max_x); } this.y_size = (short)(black_cell_max_y + 1); this.x_size = (short)(black_cell_max_x + 1); }
/// <summary> /// 解に要素を追加する。 /// </summary> /// <param name="stamp">スタンプのオブジェクト</param> /// <param name="x">x軸方向への平行移動距離</param> /// <param name="y">y軸方向への平行移動距離</param> public void AddStampAnswer(Stamp stamp, short x, short y) { this.stamp_answer_list.Add(new Tuple <Stamp, short, short>(stamp, x, y)); }