Exemplo n.º 1
0
        public static MapControl.GraphicalHelirin ToGraphicalHelirin(HelirinState h)
        {
            if (h == null)
            {
                return(new MapControl.GraphicalHelirin());
            }
            float angle = rot_to_angle_approx(h.rot);
            int   xpix  = pos_to_px(h.xpos);
            int   ypix  = pos_to_px(h.ypos);

            return(new MapControl.GraphicalHelirin(xpix, ypix, angle, h.HasBonus(), h.frameNumber));
        }
Exemplo n.º 2
0
        public static string hs_to_string(HelirinState hs)
        {
            string xpos_str         = hs.xpos.ToString();
            string ypos_str         = hs.ypos.ToString();
            string xb_str           = hs.xb.ToString();
            string yb_str           = hs.yb.ToString();
            string rot_str          = hs.rot.ToString();
            string rot_rate_str     = hs.rot_rate.ToString();
            string rot_srate_str    = hs.rot_srate.ToString();
            string life_str         = hs.life.ToString();
            string invul_str        = hs.invul.ToString();
            string frame_number_str = hs.frameNumber.ToString();

            return(xpos_str + " " + ypos_str + " " + xb_str + " " + yb_str + " " + rot_str + " " + rot_rate_str + " " + rot_srate_str
                   + " " + life_str + " " + invul_str + " " + (hs.HasBonus() ? "1" : "0") + " " + frame_number_str + "\n");
        }
Exemplo n.º 3
0
        public Action[] Solve(HelirinState init, int min_life_score)
        {
            if (cost_maps == null || init == null)
            {
                return(null);
            }
            SimplePriorityQueue <HelirinState>   q         = new SimplePriorityQueue <HelirinState>();
            Dictionary <HelirinState, StateData> data      = new Dictionary <HelirinState, StateData>();
            Dictionary <HelirinState, int>       life_data = null;

            if (!Settings.allow_state_visit_with_less_life && Settings.invul_frames >= 0 && Settings.full_life >= 2)
            {
                life_data = new Dictionary <HelirinState, int>();
            }

            // Set range of possible inputs
            int min_input = 0;

            if (Settings.min_ab_speed == 1)
            {
                min_input = 1;
            }
            else if (Settings.min_ab_speed == 2)
            {
                min_input = 9;
            }
            else if (Settings.min_ab_speed == 3)
            {
                min_input = 17;
            }
            else if (Settings.min_ab_speed > 3)
            {
                min_input = 25;
            }

            // Init
            HelirinState norm_init  = NormaliseState(init);
            float        cost       = GetCost(init.xpos, init.ypos, init.life, init.invul, init.HasBonus());
            float        weight     = 0;
            float        total_cost = cost + weight;

            q.Enqueue(norm_init, total_cost);
            data.Add(norm_init, new StateData(init, weight, cost, null, null, false));
            if (life_data != null)
            {
                life_data.Add(ClearLifeDataOfState(norm_init), Flooding.GetRealInvul(init.life, init.invul));
            }

            // ProgressBar and preview settings
            float init_cost = cost;

            bool[,] preview = new bool[cost_maps[0][0].Get(true).Height, cost_maps[0][0].Get(true).Width];
            int since_last_update = 0;

            // A*
            HelirinState result = null;

            while (q.Count > 0 && result == null)
            {
                HelirinState norm_st = q.Dequeue();
                StateData    st_data = data[norm_st];
                st_data.already_treated = true;
                weight = st_data.weight + 1;

                // ProgressBar and preview settings
                preview[Physics.pos_to_px(st_data.exact_state.ypos) - f.PixelStart.y, Physics.pos_to_px(st_data.exact_state.xpos) - f.PixelStart.x] = true;
                since_last_update++;
                if (since_last_update >= Settings.nb_iterations_before_ui_update)
                {
                    since_last_update = 0;
                    parent.UpdateProgressBarAndHighlight(100 - st_data.cost * 100 / init_cost, preview);
                }

                for (int i = 24; i >= min_input; i--)
                {
                    Action       a        = (Action)i;
                    HelirinState nst      = p.Next(st_data.exact_state, a);
                    HelirinState norm_nst = NormaliseState(nst);

                    // Lose / Not enough life / Out of search space ?
                    int life_score = Flooding.GetRealInvul(nst.life, nst.invul);
                    if (nst.gs == GameState.Lose || (life_score < min_life_score && life_score >= 0) || IsOutOfSearchSpace(nst.xpos, nst.ypos))
                    {
                        continue;
                    }

                    // Already enqueued with more life ?
                    HelirinState cleared_nst = null;
                    if (life_data != null)
                    {
                        cleared_nst = ClearLifeDataOfState(norm_nst);
                        int old_life_score;
                        life_data.TryGetValue(cleared_nst, out old_life_score); // Default value for 'old_life_score' (type int) is 0.
                        if (old_life_score > life_score)
                        {
                            continue;
                        }
                    }

                    // Already visited ?
                    // If the state was already visited, we should not add it to the queue again! Otherwise it could overwrite the state entry and corrupt some paths.
                    StateData old;
                    data.TryGetValue(norm_nst, out old); // Default value for 'old' (type StateData) is null.
                    if (old != null && old.already_treated)
                    {
                        continue;
                    }

                    // Keep only if it is a non-infinite better cost
                    cost = GetCost(nst.xpos, nst.ypos, nst.life, nst.invul, nst.HasBonus());
                    if (cost >= float.PositiveInfinity)
                    {
                        continue;
                    }
                    total_cost = cost + weight;
                    if (old != null && total_cost >= old.cost + old.weight)
                    {
                        continue;
                    }

                    // Is the state terminal without having completed the objective?
                    if (cost > 0 && nst.IsTerminal())
                    {
                        continue;
                    }

                    // Everything's okay, we add the config to the data and queue

                    StateData nst_data = new StateData(nst, weight, cost, a, norm_st, false);
                    data[norm_nst] = nst_data;
                    if (life_data != null)
                    {
                        life_data[cleared_nst] = life_score;
                    }

                    // Target reached ? We look at the cost rather than the game state, because the target can be different than winning
                    if (cost <= 0)
                    {
                        result = norm_nst;
                        break;
                    }

                    // We don't use UpdatePriority because it does not change the InsertionIndex (first-in, first-out)
                    if (old != null)
                    {
                        q.Remove(norm_nst);
                    }
                    q.Enqueue(norm_nst, total_cost);

                    /*
                     * if (old == null)
                     *  q.Enqueue(norm_nst, total_cost);
                     * else
                     *  q.UpdatePriority(norm_nst, total_cost);
                     */
                }
            }

            // Retrieve full path
            if (result == null)
            {
                return(null);
            }
            List <Action> res = new List <Action>();

            while (result != null)
            {
                StateData sd = data[result];
                if (sd.action.HasValue)
                {
                    res.Add(sd.action.Value);
                }
                result = sd.previous_state;
            }
            res.Reverse();
            return(res.ToArray());
        }