Ejemplo n.º 1
0
        public List<State> Solve (List<Measure> measures, ICostFactory cost_factory, OnProgressDelegate on_progress) {
            List<NodeCollection> node_collections = NodeCollection.CalculateNodes(measures);
            List<List<NodeCollection>> sections = NodeCollection.CalculateSections(node_collections, m_DesiredSectionSize);
            State initial = SolverHelper.GenerateInitialNode(measures[0].beats[0].notes.Count == 10, cost_factory);

            OnProgressArg on_progress_arg = new OnProgressArg();
            on_progress_arg.second_max = node_collections[node_collections.Count - 1].items[0].second;
            on_progress_arg.depth_max = node_collections.Count - 1;
            on_progress_arg.depth_cur = 0;
            foreach (List<NodeCollection> path in sections) {
                State nxt = null;
                while (nxt == null) {
                    Calculate(path, initial, cost_factory, on_progress, on_progress_arg, ref nxt);

                    on_progress(on_progress_arg);
                    if (!on_progress_arg.carry_on) {
                        return SolverHelper.GeneratePlay(nxt == null ? initial : nxt);
                    }
                }
                on_progress_arg.prv_iter_opened_total = on_progress_arg.opened_total;
                on_progress_arg.prv_iter_discarded = on_progress_arg.discarded;

                initial = nxt;
                on_progress_arg.depth_cur += path.Count;
            }
            return SolverHelper.GeneratePlay(initial);
        }
Ejemplo n.º 2
0
        public List<State> Solve (List<Measure> measures, ICostFactory cost_factory, OnProgressDelegate on_progress) {
            List<NodeCollection> node_collections = NodeCollection.CalculateNodes(measures);
            List<List<NodeCollection>> sections = NodeCollection.CalculateSections(node_collections, m_DesiredSectionSize);
            State initial = SolverHelper.GenerateInitialNode(measures[0].beats[0].notes.Count == 10, cost_factory);

            OnProgressArg on_progress_arg = new OnProgressArg();
            on_progress_arg.second_max = node_collections[node_collections.Count - 1].items[0].second;
            on_progress_arg.depth_max = node_collections.Count - 1;
            foreach (List<NodeCollection> path in sections) {
                State nxt = null;
                float storage_ratio = (float)path.Count / 30.0f;
                if (storage_ratio < 1.0f) {
                    storage_ratio = 1.0f;
                }
                int storage_limit = (int)((float)m_ItemLimit * storage_ratio);
                while (nxt == null) {
                    if (storage_limit > 100000) { //Arbitrary limit
                        throw new Exception("Storage limit reached without a solution");
                    }
                    nxt = Calculate(initial, path, storage_limit, cost_factory, on_progress, on_progress_arg);
                    storage_limit += m_ItemLimit;

                    on_progress(on_progress_arg);
                    if (!on_progress_arg.carry_on) {
                        return SolverHelper.GeneratePlay(nxt == null ? initial : nxt);
                    }
                }
                on_progress_arg.prv_iter_opened_total = on_progress_arg.opened_total;
                on_progress_arg.prv_iter_discarded = on_progress_arg.discarded;

                initial = nxt;
            }
            return SolverHelper.GeneratePlay(initial);
        }
Ejemplo n.º 3
0
        private void Calculate (List<NodeCollection> node_collections, State cur, ICostFactory cost_factory, OnProgressDelegate on_progress, OnProgressArg on_progress_arg, ref State best) {
            on_progress_arg.progress_cur = (int)(
                (
                    (float)(cur.distance_from_start + 1) /
                    (float)(on_progress_arg.depth_max)
                ) * 100.0f
            );
            on_progress(on_progress_arg);

            if (cur.distance_from_start == node_collections.Count - 1) {
                //This is a completed play
                if (best == null) {
                    best = cur;
                } else if (cur.cost.GetTotalCost() < best.cost.GetTotalCost()) {
                    best = cur;
                }
                return;
            }
            if (!on_progress_arg.carry_on) {
                return;
            }
            int index = cur.distance_from_start + 1;
            NodeCollection collection = node_collections[index];
            Beat beat = collection.beat;

            List<State> nxt_list = new List<State>();
            foreach (Node node in collection.items) {
                List<Analyzer.State.Limb[]> neighbours = new List<Analyzer.State.Limb[]>();
                ArcCalculator.Calculate(cur, node, neighbours);
                foreach (Analyzer.State.Limb[] n in neighbours) {
                    State nxt = ArcCalculator.TransitionTo(cur, n, collection.beat.second, index, beat, cost_factory);
                    if (nxt == null) {
                        continue;
                    }
                    if (best == null || nxt.cost.GetTotalCost() < best.cost.GetTotalCost()) {
                        nxt_list.Add(nxt);
                    }
                }
            }
            nxt_list.Sort((State a, State b) => {
                return a.cost.GetTotalCost().CompareTo(b.cost.GetTotalCost());
            });
            foreach (State n in nxt_list) {
                Calculate(node_collections, n, cost_factory, on_progress, on_progress_arg, ref best);
            }
        }
Ejemplo n.º 4
0
 public static State GenerateInitialNode (bool is_double, ICostFactory cost_factory) {
     State initial = new State(null, 0.0f, -1, false);
     initial.limbs[0] = new Analyzer.State.Limb();
     initial.limbs[1] = new Analyzer.State.Limb();
     if (is_double) {
         initial.limbs[0].main = new Analyzer.State.Part(
             Analyzer.State.Movement.PassiveDown,
             Panel.Panels_1D_Playable[4],
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[0].sub = new Analyzer.State.Part(
             Analyzer.State.Movement.PassiveDown,
             Panel.Panels_1D_Playable[3],
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[0].extra = new Analyzer.State.Part(
             Analyzer.State.Movement.Unknown,
             null,
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[1].main = new Analyzer.State.Part(
             Analyzer.State.Movement.PassiveDown,
             Panel.Panels_1D_Playable[5],
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[1].sub = new Analyzer.State.Part(
             Analyzer.State.Movement.PassiveDown,
             Panel.Panels_1D_Playable[6],
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[1].extra = new Analyzer.State.Part(
             Analyzer.State.Movement.Unknown,
             null,
             0.0f, 0.0f, 0.0f
         );
     } else {
         initial.limbs[0].main = new Analyzer.State.Part(
             Analyzer.State.Movement.PassiveDown,
             Panel.Panels_1D_Playable[0],
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[0].sub = new Analyzer.State.Part(
             Analyzer.State.Movement.PassiveDown,
             Panel.Panels_1D_Playable[1],
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[0].extra = new Analyzer.State.Part(
             Analyzer.State.Movement.Unknown,
             null,
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[1].main = new Analyzer.State.Part(
             Analyzer.State.Movement.PassiveDown,
             Panel.Panels_1D_Playable[4],
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[1].sub = new Analyzer.State.Part(
             Analyzer.State.Movement.PassiveDown,
             Panel.Panels_1D_Playable[3],
             0.0f, 0.0f, 0.0f
         );
         initial.limbs[1].extra = new Analyzer.State.Part(
             Analyzer.State.Movement.Unknown,
             null,
             0.0f, 0.0f, 0.0f
         );
     }
     initial.facing = new Vector(0.0f, 1.0f);
     initial.facing_desired = new Vector(0.0f, 1.0f);
     initial.sanityCheck();
     initial.cost = cost_factory.Calculate(initial);
     return initial;
 }
Ejemplo n.º 5
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;
 }
Ejemplo n.º 6
0
        public static State Calculate (
            State initial, List<NodeCollection> path,
            int storage_limit, ICostFactory cost_factory,
            OnProgressDelegate on_progress, OnProgressArg arg
        ) {
            int path_offset = initial.distance_from_start + 1;

            OpenedStateCollection opened = new OpenedStateCollection(storage_limit, 1000/*magic number*/, new StateComparer(0.2f/*magic number*/));
            opened.Add(initial);
            State prv_opened = null;
            State result = null;

            List<State> tmp = new List<State>();
            while (opened.Commit()) {
                State cur = opened.First();
                int nxt_distance_from_start = cur.distance_from_start + 1;
                int path_index = nxt_distance_from_start - path_offset;
                if (path_index == path.Count) {
                    if (result == null || result.cost.GetTotalCost() > cur.cost.GetTotalCost()) {
                        result = cur;
                    }
                    continue;
                }
                prv_opened = cur;
                Beat beat = path[path_index].beat;
                List<Node> neighbours = path[path_index].items;

                if (on_progress != null) {
                    arg.progress_cur = (int)((float)nxt_distance_from_start / (float)arg.depth_max * 100.0f);
                    arg.depth_cur = nxt_distance_from_start;
                    arg.second_cur = cur.second;

                    ++arg.closed;

                    arg.opened_cur = opened.Count();
                    arg.opened_total = arg.prv_iter_opened_total + opened.GetTotalAdded();
                    arg.discarded = arg.prv_iter_discarded + opened.GetTotalDiscarded();

                    on_progress(arg);
                    if (!arg.carry_on) {
                        return result;
                    }
                }
                if (neighbours.Count == 0) {
                    throw new ExecutionEngineException();
                } else {
                    //tmp.Clear();
                    foreach (Node n in neighbours) {
                        if (!ArcCalculator.IsArcValid(cur, n)) {
                            continue;
                        }
                        List<Analyzer.State.Limb[]> possibilities = new List<Analyzer.State.Limb[]>();
                        ArcCalculator.Calculate(cur, n, possibilities);
                        foreach (Analyzer.State.Limb[] p in possibilities) {
                            State nxt = ArcCalculator.TransitionTo(cur, p, n.second, n.distance_from_start, beat, cost_factory);
                            if (nxt != null) {
                                //tmp.Add(nxt);
                                opened.Add(nxt);
                            }
                        }
                    }
                }
            }
            return result;
        }