Exemple #1
0
 public static Limb DirectCopy (Limb src) {
     Limb result = new Limb();
     for (int i = 0; i < result.m_Parts.Length; ++i) {
         result[i] = Part.DirectCopy(src.m_Parts[i]);
     }
     return result;
 }
Exemple #2
0
 public static Vector Calculate (Limb[] limbs, Vector default_facing) {
     if (default_facing == null) { throw new ArgumentException(); }
     float dx = 0.0f;
     float dy = 0.0f;
     int count = 0;
     for (int a = 0; a < Limb.PART_COUNT; ++a) {
         Part part_a = limbs[0][a];
         if (part_a.IsUnknown()) { continue; }
         for (int b = 0; b < Limb.PART_COUNT; ++b) {
             Part part_b = limbs[1][b];
             if (part_b.IsUnknown()) { continue; }
             Vector f = Panel.GetFacing(
                 part_a.panel.index, part_b.panel.index
             );
             dx += f.dx;
             dy += f.dy;
             ++count;
         }
     }
     if (count == 0) {
         return default_facing;
     } else {
         return new Vector(dx/count, dy/count);
     }
 }
Exemple #3
0
 private static bool IsValidOrNot3Bracket (Limb[] limbs) {
     foreach (Limb limb in limbs) {
         if (!IsValidOrNot3Bracket(limb == limbs[0], limb)) {
             return false;
         }
     }
     return true;
 }
Exemple #4
0
 public static void Calculate (State from, Node to, List<Limb[]> output) {
     if (!IsArcValid(from, to)) {
         return;
     }
     int hoverable_count = 0;
     Limb[] original = new Limb[from.limbs.Length];
     for (int i = 0; i < from.limbs.Length; ++i) {
         Limb from_limb = from.limbs[i];
         Analyzer.Node.Limb to_limb = to.limbs[i];
         if (to_limb == null) {
             original[i] = Limb.ToPassiveDown(from_limb, to.second);
         } else {
             original[i] = LimbHelper.TransitionToV3(from_limb, to_limb, to.second);
         }
         if (IsHoverable(original[i].main.movement)) {
             ++hoverable_count;
         }
         if (IsHoverable(original[i].sub.movement)) {
             ++hoverable_count;
         } else if (IsHoverable(original[i].extra.movement)) {
             ++hoverable_count;
         }
         original[i].sanityCheck();
     }
     if (!IsOverlapping(original) && IsValidOrNot3Bracket(original)) {
         output.Add(original);
     }
     if (hoverable_count >= 2) {
         for (int limb_index = 0; limb_index < from.limbs.Length; ++limb_index) {
             Limb limb = original[limb_index];
             if (IsHoverable(limb.main.movement)) {
                 Limb[] with_unknown = CloneWithHover(original, limb_index, to.second, 0);
                 if (!IsOverlapping(with_unknown) && IsValidOrNot3Bracket(with_unknown)) {
                     output.Add(with_unknown);
                 }
             }
             if (IsHoverable(limb.sub.movement)) {
                 if (IsHoverable(limb.extra.movement)) {
                     Limb[] with_unknown = CloneWithHover(original, limb_index, to.second, 1, 2);
                     if (!IsOverlapping(with_unknown) && IsValidOrNot3Bracket(with_unknown)) {
                         output.Add(with_unknown);
                     }
                 } else {
                     Limb[] with_unknown = CloneWithHover(original, limb_index, to.second, 1);
                     if (!IsOverlapping(with_unknown) && IsValidOrNot3Bracket(with_unknown)) {
                         output.Add(with_unknown);
                     }
                 }
             } else if (IsHoverable(limb.extra.movement)) {
                 Limb[] with_unknown = CloneWithHover(original, limb_index, to.second, 2);
                 if (!IsOverlapping(with_unknown) && IsValidOrNot3Bracket(with_unknown)) {
                     output.Add(with_unknown);
                 }
             }
         }
     }
 }
Exemple #5
0
 public static bool IsArcValid (Limb from, Analyzer.Node.Limb to) {
     if (to == null) { return true; }
     for (int i = 0; i < Limb.PART_COUNT; ++i) {
         if (!PartHelper.IsArcValid(from[i], to[i])) {
             return false;
         }
     }
     return true;
 }
Exemple #6
0
 public static Limb ToPassiveDown (Limb src, float cur_second) {
     Limb result = new Limb();
     for (int i = 0; i < result.m_Parts.Length; ++i) {
         if (src.m_Parts[i].IsUnknown()) {
             result[i] = Part.ToUnknown(src.m_Parts[i], cur_second);
         } else {
             result[i] = Part.ToPassiveDown(src.m_Parts[i], cur_second);
         }
     }
     return result;
 }
Exemple #7
0
 private static bool IsValidOrNot3Bracket (bool is_left_leg, Limb limb) {
     return
         (
             limb.main.IsUnknown() ||
             limb.sub.IsUnknown() ||
             limb.extra.IsUnknown()
         ) ||
         Panel.IsValidOrNot3Bracket(
             is_left_leg,
             limb.main.panel.index,
             limb.sub.panel.index,
             limb.extra.panel.index
         );
 }
Exemple #8
0
 private static bool IsOverlapping (Limb[] limbs) {
     for (int a = 0; a < Limb.PART_COUNT; ++a) {
         Part part_a = limbs[0][a];
         if (part_a.IsUnknown()) { continue; }
         for (int b = 0; b < Limb.PART_COUNT; ++b) {
             Part part_b = limbs[1][b];
             if (part_b.IsUnknown()) { continue; }
             if (part_a.panel == part_b.panel) {
                 return true;
             }
         }
     }
     return false;
 }
Exemple #9
0
 public Fail (Limb limb) {
     main_sub = !Panel.IsBracketable(
             limb.main.panel.index,
             limb.sub.panel.index
         );
     main_extra = !Panel.IsBracketable(
         limb.main.panel.index,
         limb.extra.panel.index
     );
     sub_extra = (limb.sub.panel == limb.extra.panel) ?
         false :
         !Panel.IsSubBracketable(
             limb.sub.panel.index,
             limb.extra.panel.index
         );
 }
Exemple #10
0
 public static Limb[] CloneWithHover (Limb[] src, int limb_index, float cur_second, params int[] part_index) {
     Limb[] dst = new Limb[src.Length];
     for (int i = 0; i < src.Length; ++i) {
         dst[i] = Limb.DirectCopy(src[i]);
         if (i == limb_index) {
             foreach (int p in part_index) {
                 dst[i][p] = new Part(
                     Movement.Unknown,
                     null,
                     dst[i][p].cur_second,
                     dst[i][p].cur_moved_second,
                     dst[i][p].prv_moved_second
                 );
             }
         }
         dst[i].sanityCheck();
     }
     return dst;
 }
Exemple #11
0
 public static State TransitionTo (State from, Limb[] to, float second, int distance_from_start, Beat beat, ICostFactory cost_factory) {
     State nxt = null;
     Vector facing = FacingCalculator.Calculate(to, from.facing);
     Vector facing_desired = FacingCalculator.CalculateDesiredFacing(facing, from.facing_desired);
     if (IsArcValidWithoutCrossing(to, facing_desired)) {
         nxt = new State(from, second, distance_from_start, false);
     } else if (IsArcValidWithCrossing(to, facing_desired)) {
         //nxt = new State(from, second, distance_from_start, true);
         return null;
     } else {
         return null;
     }
     //Transition
     for (int i = 0; i < from.limbs.Length; ++i) {
         nxt.limbs[i] = to[i];
     }
     nxt.beat = beat;
     nxt.facing = facing;
     nxt.facing_desired = facing_desired;
     nxt.sanityCheck();
     nxt.cost = cost_factory.Calculate(nxt);
     return nxt;
 }
Exemple #12
0
 public static bool IsArcValidWithCrossing (Limb[] to, Vector facing) {
     float facing_rad = facing.toRadian();
     foreach (Limb limb in to) {
         if (
             !limb.main.IsUnknown() &&
             !limb.sub.IsUnknown() &&
             !Panel.IsBracketableDirection(
                 facing_rad,
                 limb == to[1],
                 limb.main.panel.index,
                 limb.sub.panel.index
             )
         ) {
             return false;
         }
         if (
             !limb.main.IsUnknown() &&
             !limb.extra.IsUnknown() &&
             !Panel.IsBracketableDirection(
                 facing_rad,
                 limb == to[1],
                 limb.main.panel.index,
                 limb.extra.panel.index
             )
         ) {
             return false;
         }
     }
     return true;
 }
Exemple #13
0
        public static Limb TransitionToV3 (Limb from, Analyzer.Node.Limb to, float cur_second) {
            if (!IsArcValid(from, to)) {
                throw new ArgumentException();
            }

            if (to == null) {
                throw new ArgumentException();
            } else {
                Limb nxt = new Limb();
                for (int i = 0; i < Limb.PART_COUNT; ++i) {
                    Part from_part = from[i];
                    Analyzer.Node.Part to_part = to[i];
                    Part part;
                    if (to_part == null) {
                        if (from_part.IsUnknown()) {
                            part = Part.ToUnknown(from_part, cur_second);
                        } else {
                            part = Part.ToPassiveDown(from_part, cur_second);
                        }
                    } else {
                        if (PartHelper.IsArcValid(from_part, to_part)) {
                            part = PartHelper.TransitionTo(from_part, to_part, cur_second);
                        } else {
                            throw new ArgumentException();
                        }
                    }
                    nxt[i] = part;
                }
                FixInvalidBracket(nxt);
                nxt.sanityCheck();
                return nxt;
            }
        }
Exemple #14
0
 private static void FixInvalidBracket (Limb limb) {
     if (
         !limb.main.IsUnknown() &&
         !limb.sub.IsUnknown() &&
         (
             limb.main.panel == limb.sub.panel ||
             !Panel.IsBracketable(
                 limb.main.panel.index,
                 limb.sub.panel.index
             )
         )
     ) {
         if (limb.main.IsPassiveDown()) {
             limb.main = Part.ToUnknown(limb.main);
         } else {
             limb.sub = Part.ToUnknown(limb.sub);
         }
     }
     if (
         !limb.main.IsUnknown() &&
         !limb.extra.IsUnknown() &&
         (
             limb.main.panel == limb.extra.panel ||
             !Panel.IsBracketable(
                 limb.main.panel.index,
                 limb.extra.panel.index
             )
         )
     ) {
         if (limb.main.IsPassiveDown()) {
             limb.main = Part.ToUnknown(limb.main);
         } else {
             limb.extra = Part.ToUnknown(limb.extra);
         }
     }
     if (
         !limb.sub.IsUnknown() &&
         !limb.extra.IsUnknown() &&
         (
             limb.sub.panel == limb.extra.panel ||
             !Panel.IsSubBracketable(
                 limb.sub.panel.index,
                 limb.extra.panel.index
             )
         )
     ) {
         if (limb.sub.IsPassiveDown()) {
             limb.sub = Part.ToUnknown(limb.sub);
         } else {
             limb.extra = Part.ToUnknown(limb.extra);
         }
     }
 }
Exemple #15
0
        public static Limb TransitionTo (Limb from, Analyzer.Node.Limb to, float cur_second) {
            if (!IsArcValid(from, to)) {
                throw new ArgumentException();
            }

            if (to == null) {
                throw new ArgumentException();
                /*Limb nxt = new Limb();
                for (int i = 0; i < Limb.PART_COUNT; ++i) {
                    Part part = PartHelper.TransitionTo(from[i], null, cur_second);
                    nxt[i] = part;
                }
                nxt.sanityCheck();
                return nxt;*/
            } else {
                Limb nxt = new Limb();
                for (int i = 0; i < Limb.PART_COUNT; ++i) {
                    Part part = PartHelper.TransitionTo(from[i], to[i], cur_second);
                    nxt[i] = part;
                }
                if (to[Analyzer.Node.Limb.INDEX_EXTRA] == null) {
                    nxt.extra = nxt.sub;
                }
                bool has_main = to.main != null;
                bool has_sub = to.sub != null;
                bool has_extra = to.extra != null;
                Fail fail = new Fail(nxt);
                if (has_main) {
                    if (has_sub) {
                        if (has_extra) {
                            //main+sub+extra
                            if (fail.main_sub) {
                                throw new ArgumentException();
                            }
                            if (fail.main_extra) {
                                throw new ArgumentException();
                            }
                            if (fail.sub_extra) {
                                throw new ArgumentException();
                            }
                        } else {
                            //main+sub
                            if (fail.main_sub) {
                                throw new ArgumentException();
                            }
                            if (fail.main_extra) {
                                nxt.extra = nxt.sub;
                                fail = new Fail(nxt);
                            }
                            if (fail.sub_extra) {
                                nxt.extra = nxt.sub;
                                fail = new Fail(nxt);
                            }
                        }
                    } else if (has_extra) {
                        //main+extra
                        if (fail.main_sub) {
                            nxt.sub = nxt.extra;
                            fail = new Fail(nxt);
                        }
                        if (fail.main_extra) {
                            throw new ArgumentException();
                        }
                        if (fail.sub_extra) {
                            nxt.sub = nxt.extra;
                            fail = new Fail(nxt);
                        }
                    } else {
                        //main
                        if (fail.main_sub) {
                            Panel n = Panel.CalculateBestBracketable(nxt.main.panel, nxt.sub.panel);
                            Part src = nxt.sub;
                            nxt.sub = new Part(
                                Movement.Unknown,
                                n,
                                src.cur_second,
                                cur_second,
                                src.cur_moved_second == cur_second ?
                                    src.prv_moved_second : src.cur_moved_second
                            );
                            fail = new Fail(nxt);
                        }
                        if (fail.main_extra) {
                            nxt.extra = nxt.sub;
                            fail = new Fail(nxt);
                        }
                        if (fail.sub_extra) {
                            throw new ArgumentException();
                        }
                    }
                } else if (has_sub) {
                    if (has_extra) {
                        //sub+extra
                        if (fail.main_sub) {
                            Panel n = Panel.CalculateBestBracketable(nxt.sub.panel, nxt.main.panel);
                            Part src = nxt.main;
                            nxt.main = new Part(
                                Movement.Unknown,
                                n,
                                src.cur_second,
                                cur_second,
                                src.cur_moved_second == cur_second ?
                                    src.prv_moved_second : src.cur_moved_second
                            );
                            fail = new Fail(nxt);
                        }
                        if (fail.main_extra) {
                            Panel n = Panel.CalculateBestBracketable(nxt.extra.panel, nxt.main.panel);
                            Part src = nxt.main;
                            nxt.main = new Part(
                                Movement.Unknown,
                                n,
                                src.cur_second,
                                cur_second,
                                src.cur_moved_second == cur_second ?
                                    src.prv_moved_second : src.cur_moved_second
                            );
                            fail = new Fail(nxt);
                        }
                        if (fail.sub_extra) {
                            throw new ArgumentException();
                        }
                    } else {
                        //sub
                        if (fail.main_sub) {
                            Panel n = Panel.CalculateBestBracketable(nxt.sub.panel, nxt.main.panel);
                            Part src = nxt.main;
                            nxt.main = new Part(
                                Movement.Unknown,
                                n,
                                src.cur_second,
                                cur_second,
                                src.cur_moved_second == cur_second ?
                                    src.prv_moved_second : src.cur_moved_second
                            );
                            fail = new Fail(nxt);
                        }
                        if (fail.main_extra) {
                            throw new ArgumentException();
                        }
                        if (fail.sub_extra) {
                            nxt.extra = nxt.sub;
                            fail = new Fail(nxt);
                        }
                    }
                } else if (has_extra) {
                    //extra
                    if (fail.main_sub) {
                        throw new ArgumentException();
                    }
                    if (fail.main_extra) {
                        Panel n = Panel.CalculateBestBracketable(nxt.extra.panel, nxt.main.panel);
                        Part src = nxt.main;
                        nxt.main = new Part(
                            Movement.Unknown,
                            n,
                            src.cur_second,
                            cur_second,
                            src.cur_moved_second == cur_second ?
                                src.prv_moved_second : src.cur_moved_second
                        );
                        fail = new Fail(nxt);
                    }
                    if (fail.sub_extra) {
                        nxt.sub = nxt.extra;
                        fail = new Fail(nxt);
                    }
                } else {
                    //NOTHING
                    if (fail.main_sub) {
                        throw new ArgumentException();
                    }
                    if (fail.main_extra) {
                        throw new ArgumentException();
                    }
                    if (fail.sub_extra) {
                        throw new ArgumentException();
                    }
                }
                if (fail.main_sub || fail.main_extra || fail.sub_extra) {
                    throw new ArgumentException();
                }
                nxt.sanityCheck();
                return nxt;
            }
        }
Exemple #16
0
        public static List<Limb> TransitionToV2 (Limb from, Analyzer.Node.Limb to, float cur_second) {
            if (!IsArcValid(from, to)) {
                throw new ArgumentException();
            }
            if (to == null) {
                throw new ArgumentException();
            }

            List<Limb> result = new List<Limb>();

            Limb nxt = new Limb();
            for (int i = 0; i < Limb.PART_COUNT; ++i) {
                Part part = PartHelper.TransitionTo(from[i], to[i], cur_second);
                nxt[i] = part;
            }
            if (to[Analyzer.Node.Limb.INDEX_EXTRA] == null) {
                nxt.extra = nxt.sub;
            }
            bool has_main = to.main != null;
            bool has_sub = to.sub != null;
            bool has_extra = to.extra != null;
            Fail fail = new Fail(nxt);
            if (has_main) {
                if (has_sub) {
                    if (has_extra) {
                        //main+sub+extra
                        if (fail.main_sub) {
                            //throw new ArgumentException();
                        }
                        if (fail.main_extra) {
                            //throw new ArgumentException();
                        }
                        if (fail.sub_extra) {
                            //throw new ArgumentException();
                        }
                    } else {
                        //main+sub
                        if (fail.main_sub) {
                            //throw new ArgumentException();
                        }
                        if (fail.main_extra) {
                            nxt.extra = nxt.sub;
                            fail = new Fail(nxt);
                        }
                        if (fail.sub_extra) {
                            nxt.extra = nxt.sub;
                            fail = new Fail(nxt);
                        }
                    }
                } else if (has_extra) {
                    //main+extra
                    if (fail.main_sub) {
                        nxt.sub = nxt.extra;
                        fail = new Fail(nxt);
                    }
                    if (fail.main_extra) {
                        //throw new ArgumentException();
                    }
                    if (fail.sub_extra) {
                        nxt.sub = nxt.extra;
                        fail = new Fail(nxt);
                    }
                } else {
                    //main
                    if (fail.main_sub) {
                        List<Panel> neighbours = Panel.Neighbours_1D[nxt.main.panel.index];
                        foreach (Panel n in neighbours) {
                            Limb copy = Limb.DirectCopy(nxt);
                            Part src = copy.sub;
                            copy.sub = new Part(
                                Movement.Unknown,
                                n,
                                src.cur_second,
                                cur_second,
                                src.cur_moved_second == cur_second ?
                                    src.prv_moved_second : src.cur_moved_second
                            );

                            Fail copy_fail = new Fail(copy);
                            if (copy_fail.main_extra) {
                                copy.extra = copy.sub;
                            }
                            AddIfValid(result, copy);
                        }
                    }
                    if (fail.main_extra) {
                        nxt.extra = nxt.sub;
                        fail = new Fail(nxt);
                    }
                    if (fail.sub_extra) {
                        //throw new ArgumentException();
                    }
                }
            } else if (has_sub) {
                if (has_extra) {
                    //sub+extra
                    if (fail.main_sub) {
                        List<Panel> neighbours = Panel.Neighbours_1D[nxt.sub.panel.index];
                        foreach (Panel n in neighbours) {
                            Limb copy = Limb.DirectCopy(nxt);
                            Part src = copy.main;
                            copy.main = new Part(
                                Movement.Unknown,
                                n,
                                src.cur_second,
                                cur_second,
                                src.cur_moved_second == cur_second ?
                                    src.prv_moved_second : src.cur_moved_second
                            );

                            Fail copy_fail = new Fail(copy);
                            if (copy_fail.main_extra) {
                                List<Panel> neighbours_2 = Panel.Neighbours_1D[nxt.extra.panel.index];
                                foreach (Panel n_2 in neighbours_2) {
                                    Limb copy_2 = Limb.DirectCopy(copy);
                                    Part src_2 = copy_2.main;
                                    copy_2.main = new Part(
                                        Movement.Unknown,
                                        n_2,
                                        src_2.cur_second,
                                        cur_second,
                                        src_2.cur_moved_second == cur_second ?
                                            src_2.prv_moved_second : src_2.cur_moved_second
                                    );
                                    AddIfValid(result, copy_2);
                                }
                            }
                            AddIfValid(result, copy);
                        }
                    }
                    if (fail.main_extra) {
                        List<Panel> neighbours_2 = Panel.Neighbours_1D[nxt.extra.panel.index];
                        foreach (Panel n_2 in neighbours_2) {
                            Limb copy_2 = Limb.DirectCopy(nxt);
                            Part src_2 = copy_2.main;
                            copy_2.main = new Part(
                                Movement.Unknown,
                                n_2,
                                src_2.cur_second,
                                cur_second,
                                src_2.cur_moved_second == cur_second ?
                                    src_2.prv_moved_second : src_2.cur_moved_second
                            );
                            AddIfValid(result, copy_2);
                        }
                    }
                    if (fail.sub_extra) {
                        //throw new ArgumentException();
                    }
                } else {
                    //sub
                    if (fail.main_sub) {
                        List<Panel> neighbours = Panel.Neighbours_1D[nxt.sub.panel.index];
                        foreach (Panel n in neighbours) {
                            Limb copy = Limb.DirectCopy(nxt);
                            Part src = copy.main;
                            copy.main = new Part(
                                Movement.Unknown,
                                n,
                                src.cur_second,
                                cur_second,
                                src.cur_moved_second == cur_second ?
                                    src.prv_moved_second : src.cur_moved_second
                            );

                            Fail copy_fail = new Fail(copy);
                            if (copy_fail.main_extra) {
                                //do nothing
                            }
                            if (copy_fail.sub_extra) {
                                copy.extra = copy.sub;
                            }
                            AddIfValid(result, copy);
                        }
                    }
                    if (fail.main_extra) {
                        //throw new ArgumentException();
                    }
                    if (fail.sub_extra) {
                        nxt.extra = nxt.sub;
                    }
                }
            } else if (has_extra) {
                //extra
                if (fail.main_sub) {
                    //throw new ArgumentException();
                }
                if (fail.main_extra) {
                    List<Panel> neighbours = Panel.Neighbours_1D[nxt.extra.panel.index];
                    foreach (Panel n in neighbours) {
                        Limb copy = Limb.DirectCopy(nxt);
                        Part src = copy.main;
                        copy.main = new Part(
                            Movement.Unknown,
                            n,
                            src.cur_second,
                            cur_second,
                            src.cur_moved_second == cur_second ?
                                src.prv_moved_second : src.cur_moved_second
                        );

                        Fail copy_fail = new Fail(copy);
                        if (copy_fail.sub_extra) {
                            copy.sub = copy.extra;
                        }
                        AddIfValid(result, copy);
                    }
                }
                if (fail.sub_extra) {
                    nxt.sub = nxt.extra;
                }
            } else {
                //NOTHING
                if (fail.main_sub) {
                    //throw new ArgumentException();
                }
                if (fail.main_extra) {
                    //throw new ArgumentException();
                }
                if (fail.sub_extra) {
                    //throw new ArgumentException();
                }
            }
            AddIfValid(result, nxt);
            return result;
        }
Exemple #17
0
 private static void AddIfValid (List<Limb> list, Limb item) {
     Fail fail = new Fail(item);
     if (fail.main_sub || fail.main_extra || fail.sub_extra) {
         return;
     }
     item.sanityCheck();
     list.Add(item);
 }