当前位置: 首页>>代码示例>>C#>>正文


C# IGameState.GetIsPassable方法代码示例

本文整理汇总了C#中IGameState.GetIsPassable方法的典型用法代码示例。如果您正苦于以下问题:C# IGameState.GetIsPassable方法的具体用法?C# IGameState.GetIsPassable怎么用?C# IGameState.GetIsPassable使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在IGameState的用法示例。


在下文中一共展示了IGameState.GetIsPassable方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: DoTurn

        // DoTurn is run once per turn
        public override void DoTurn(IGameState state)
        {
            // loop through all my ants and try to give them orders
            foreach (Ant ant in state.MyAnts)
            {
                // try all the directions
                foreach (Direction direction in Ants.Aim.Keys)
                {
                    // GetDestination will wrap around the map properly
                    // and give us a new location
                    Location newLoc = state.GetDestination(ant, direction);

                    // GetIsPassable returns true if the location is land
                    if (state.GetIsPassable(newLoc) && !(orders.Contains(newLoc)))
                    {
                        IssueOrder(ant, direction);
                        orders.Add(newLoc);
                        break;
                    }
                }

                // check if we have time left to calculate more orders
                if (state.TimeRemaining < 10) break;
            }
            orders.Clear();
        }
开发者ID:TRdeBie,项目名称:KI_Project1,代码行数:27,代码来源:MyBot.cs

示例2: AddLocation

 public void AddLocation(Location location, IGameState state)
 {
     //Sets whether a tile is dirt or water
     char tile = 'u';
     if (state.GetIsPassable(location)) tile = 'd';
     else tile = 'w';
     map[location.Col, location.Row].type = tile;
 }
开发者ID:TRdeBie,项目名称:KI_Project1,代码行数:8,代码来源:Map.cs

示例3: FindNextLocation

    public static Location FindNextLocation(Location start, Location dest, IGameState state, List<Location> avoid, LayeredInfluenceMap heat)
    {
        if (start.Equals(dest) || !state.GetIsPassable(dest) || avoid.Contains(dest))
            return null;

        List<Location> list = FindPath(start, dest, state, avoid, heat);
        if (list != null)
            return list[0];
        else
            return null;
    }
开发者ID:Lapixx,项目名称:CS-UU-KI1,代码行数:11,代码来源:Pathfinding.cs

示例4: FindNextLocation

    public static Location FindNextLocation(Location start, Location dest, IGameState state)
    {
        if (start.Equals(dest) || !state.GetIsPassable(dest))
            return null;

        List<Location> list = FindPath(start, dest, state);
        if (list != null)
            return list[0];
        else
            return null;
    }
开发者ID:Lapixx,项目名称:CS-UU-KI2,代码行数:11,代码来源:Pathfinding.cs

示例5: DoTurn

        // DoTurn is run once per turn
        public override void DoTurn(IGameState state)
        {
            #if DEBUG
            System.Diagnostics.Debug.WriteLine(string.Format("{0}: Starting turn {1}", DateTime.Now.ToLongTimeString(), turnCounter), "TURN");
            #endif

            // loop through all my ants and try to give them orders
            foreach (Ant ant in state.MyAnts)
            {

                // try all the directions
                foreach (Direction direction in Ants.Aim.Keys)
                {

                    // GetDestination will wrap around the map properly
                    // and give us a new location
                    Location newLoc = state.GetDestination(ant, direction);

                    // GetIsPassable returns true if the location is land
                    if (state.GetIsPassable(newLoc))
                    {
                        IssueOrder(ant, direction);
                        // stop now, don't give 1 and multiple orders
                        break;
                    }
                }

                // check if we have time left to calculate more orders
                if (state.TimeRemaining < 10) break;
            }

            #if DEBUG
            System.Diagnostics.Debug.WriteLine(string.Format("{0}: Ending turn {1}", DateTime.Now.ToLongTimeString(), turnCounter++), "TURN");
            if (true) { } // silly line just to set a breakpoint
            #endif
        }
开发者ID:j-c,项目名称:AntAiChallengeVsSolution,代码行数:37,代码来源:MyBot.cs

示例6: FindPath

    // Returns a list of tiles that form the shortest path between start and dest
    public static List<Location> FindPath(Location start, Location dest, IGameState state, List<Location> avoid, LayeredInfluenceMap heat = null, int maxDepth = int.MaxValue)
    {
        if (start.Equals(dest) || !state.GetIsPassable(dest) || avoid.Contains(dest))
            return null;

        HashSet<string> closed = new HashSet<string>();
        Dictionary<string, PathfindNode> locToNode = new Dictionary<string, PathfindNode>();
        List<PathfindNode> open = new List<PathfindNode>();

        List<Location> reachable;

        PathfindNode first = new PathfindNode(start, null, dest, state, heat[start]);
        open.Add(first);
        locToNode.Add(MyBot.LocationToKey(first.Position), first);

        // Repeat until the destination node is reached
        PathfindNode last = null;
        while (open.Count > 0)
        {
            if (state.TimeRemaining < 10)
            {
                MyBot.LogShit("timeout.txt", "stop B - " + state.TimeRemaining);
                return null;
            }

            // Search the best available tile (lowest cost to reach from start, closest to dest)

            PathfindNode best = null;
            foreach (PathfindNode next in open)
            {
                if (best == null)
                    best = next;

                if (next.F < best.F)
                    best = next;
            }

            if (best.G > maxDepth)
                return null;

            //PathfindNode best = open.Min;

            // Move to closed list
            open.Remove(best);
            locToNode.Remove(MyBot.LocationToKey(best.Position));
            closed.Add(MyBot.LocationToKey(best.Position));

            if (best.Position.Equals(dest)) // Destination added to closed list - almost done!
            {
                last = best;
                break;
            }

            // Find tiles adjacent to this tile
            reachable = GetNeighbours(best.Position, state);
            string lid;
            PathfindNode pfn;
            foreach (Location next in reachable)
            {
                if (!state.GetIsPassable(next) || avoid.Contains(next)) // Check if tile is blocked
                    continue;

                lid = MyBot.LocationToKey(next);

                if (closed.Contains(lid))
                    continue;

                if(locToNode.ContainsKey(lid))
                {
                    pfn = locToNode[lid];
                    if (best.G + 1 < pfn.G)
                        pfn.Parent = best;
                }
                else{
                    pfn = new PathfindNode(next, best, dest, state, heat[next]);
                    open.Add(pfn);
                    locToNode.Add(lid, pfn);
                }
            }
        }

        if (last == null)
            return null;

        // Trace the route from destination to start (using each node's parent property)
        List<PathfindNode> route = new List<PathfindNode>();
        while (last != first && last != null)
        {
            route.Add(last);
            last = last.Parent;
        }

        // Reverse route and convert to Points
        List<Location> path = new List<Location>();
        for (int i = route.Count - 1; i >= 0; i--)
        {
            path.Add(route[i].Position);
        }

//.........这里部分代码省略.........
开发者ID:Lapixx,项目名称:CS-UU-KI1,代码行数:101,代码来源:Pathfinding.cs

示例7: DoMoveDirection

        //Handles collision checking and movement tracking
        private bool DoMoveDirection(Location ant, Direction direction, IGameState state)
        {
            // GetDestination will wrap around the map properly
            // and give us a new location
            Location newLoc = state.GetDestination(ant, direction);

            // GetIsPassable returns true if the location is land
            if (state.GetIsPassable(newLoc) && !(orders.Contains(newLoc) && state.GetIsUnoccupied(newLoc)))
            {
                IssueOrder(ant, direction);
                orders.Add(newLoc);
            }
            return false;
        }
开发者ID:TRdeBie,项目名称:KI_Project1,代码行数:15,代码来源:MyBot.cs

示例8: DoTurn

        // DoTurn is run once per turn
        public override void DoTurn(IGameState state)
        {
            if(radius == default(int)) // Init
                radius = (int)Math.Sqrt(state.ViewRadius2) / 2;

            foreach (Agent agent in new List<Agent>(agents)) // Die
            {
                if (!state.MyAnts.Contains(new Ant(agent.location.Row, agent.location.Col, state.MyAnts[0].Team)))
                {
                    agent.decisionLog.AddReward(DIE);
                    agents.Remove(agent);
                }
            }

            foreach (Ant a in state.MyAnts) //Spawn new ants
            {
                bool spawn = true;
                foreach (Agent agent in agents)
                {
                    if (agent.location.Equals(a))
                    {
                        spawn = false;
                        break;
                    }
                }

                if (spawn)
                {
                    Agent ag = new Agent(a);
                    decisionLogs.Add(ag.decisionLog);
                    agents.Add(ag);

                    foreach (Agent age in agents) // Take food
                    {
                        if(age.path.Count > 0)
                            if (age.currentAction == Action.TakeFood && state.GetDistance(age.location, age.path[age.path.Count - 1]) <= 1)
                                age.decisionLog.AddReward(EAT);
                    }
                }
            }

            foreach(Agent agent in agents){

                if (agent.path.Count == 0)
                {
                    State s = CalculateState(agent.location, state);
                    double[] desirabilities = rewardLog.GetDesirabilities(s);
                    int i = -1;
                    HashSet<Action> aas = s.GetActions();
                    double x = random.NextDouble();
                    if (x <= exploration) // Explore
                    {
                        do
                        {
                            i = random.Next(Enum.GetValues(typeof(Action)).Length);
                        }
                        while (!aas.Contains((Action)i));
                    }
                    else // Exploit
                    {
                        x = random.NextDouble();
                        for (i = 0; i < Enum.GetValues(typeof(Action)).Length; i++)
                        {
                            if (x <= desirabilities[i])
                                break;
                            else
                                x -= desirabilities[i];
                        }
                    }

                    if (i == Enum.GetValues(typeof(Action)).Length)
                    {
                        do
                        {
                            i = random.Next(Enum.GetValues(typeof(Action)).Length);
                        }
                        while (!aas.Contains((Action)i));
                    }

                    PerformAction(agent, s, (Action)i, state);
                }

                if (agent.path.Count == 0)
                    continue;

                if (!state.GetIsPassable(agent.path[0]))
                    agent.path = Pathfinding.FindPath(agent.location, agent.path[agent.path.Count - 1], state);
                Location next = agent.path[0];
                agent.path.RemoveAt(0);

                if (state.EnemyHills.Count > 0)
                    if (state.EnemyHills.Contains(new AntHill(next.Row, next.Col, state.EnemyHills[0].Team)))
                        agent.decisionLog.AddReward(WIN);

                IssueOrder(agent.location, ((List<Direction>)state.GetDirections(agent.location, next))[0]);
                agent.location = next;
            }
        }
开发者ID:Lapixx,项目名称:CS-UU-KI2,代码行数:99,代码来源:MyBot.cs

示例9: GetRandomLocation

 public Location GetRandomLocation(Location location, IGameState state)
 {
     Location loc;
     int x, y;
     do
     {
         x = random.Next(radius) - radius / 2;
         y = random.Next(radius) - radius / 2;
         loc = (new Location(y, x) + location) % new Location(state.Height, state.Width);
     }
     while (!state.GetIsPassable(loc));
     return loc;
 }
开发者ID:Lapixx,项目名称:CS-UU-KI2,代码行数:13,代码来源:MyBot.cs

示例10: GetNearestPassable

        public Location GetNearestPassable(Location location, IGameState state)
        {
            Queue<Location> open = new Queue<Location>();
            HashSet<Location> closed = new HashSet<Location>();
            Location lx;

            open.Enqueue(location);

            while(open.Count > 0)
            {
                lx = open.Dequeue();
                if (state.GetIsPassable(lx))
                    return lx;
                closed.Add(lx);
                List<Location> ns = Pathfinding.GetNeighbours(lx, state);
                foreach (Location l in ns)
                    if(!closed.Contains(l))
                        open.Enqueue(l);
            }

            return null;
        }
开发者ID:Lapixx,项目名称:CS-UU-KI2,代码行数:22,代码来源:MyBot.cs

示例11: DoTurn

        // DoTurn is run once per turn
        public override void DoTurn(IGameState state)
        {
            this.decision.Update(state);

            //searches a path that cannot be attacked in one turn, and that does look whether another ant is in the way.
            Search search1 = new Search(state, state.GetDistance,
                (Location location) => { return state.GetIsUnoccupied(location) && !state.GetIsAttackable(location); });

            //searches a path that cannot be attacked in one turn, but that does not look whether another ant is in the way
            //so the path is planned like all friendly ants do not exist.
            Search search2 = new Search(state, state.GetDistance,
                (Location location) => { return state.GetIsPassable(location) && !state.GetIsAttackable(location); });

            //search for a path that takes in account where other friendly ants are, but does not look at enemy ants.
            Search search3 = new Search(state, state.GetDistance, state.GetIsPassable);

            foreach (Ant ant in state.MyAnts) {

                //check whether a defend ant is blocking hill because it cannot go to its defend position.
                if (ant.Mode == AntMode.Defend && ant.WaitTime > 5) {
                    foreach (AntHill hill in state.MyHills) {
                        if (ant.Equals(hill)) {
                            decision.ReportInvalidDefendPosition(ant.Target);

                            //reset ant
                            ant.Target = null;
                            ant.Route = null;
                            ant.Mode = AntMode.None;
                        }
                    }
                }

                ant.WaitTime++;

                if (ant.Mode == AntMode.None) {
                    this.decision.SetAntMode(ant);
                }

                //updates the secondary target of the ant, so gets hill or food target when needed
                decision.UpdateTarget2(ant, state);

                if (ant.Target2 != null) {

                    if (ant.Route2 == null) {
                        //only get food if youre not gonna die for it, and if no other ant is in the way (use search1).
                        //and there exists a path to the food/hill which distance is less than 1.5 times
                        //the distance between the ant and the food/hill.
                        ant.Route2 = search1.AStar(ant, ant.Target2, (int)(state.GetDistance(ant, ant.Target2) * 1.5));

                        //remove the last node if its food because we don't need to stand on it to get it.
                        if (ant.Route2 != null && state.FoodTiles.Contains(ant.Target2)) {
                            ant.Route2.RemoveAt(ant.Route2.Count - 1);
                        }
                    }

                    //if the route2 is null after recalculation, drop the target
                    if (ant.Route2 == null) {
                        ant.Target2 = null;
                    } else {
                        //only get food if no other ant is blocking it
                        if (ant.Route2.Count > 1 && state.GetIsUnoccupied(ant.Route2[1])) {
                            IssueOrder(state, ant, GetDirectionFromPath(ant.Route2, state));
                            ant.Route2.RemoveAt(0);

                                //original route has become invalid
                                ant.Route = null;
                        } else {
                            ant.Target2 = null;
                            ant.Route2 = null;
                        }
                    }
                }

                //if there exists no secundairy target, then get the primary target.
                //it is possible that there exists no target, and then no target is found.
                //therefore it we can't use an else construction but should again check if (ant.Target2 == null.)
                if (ant.Target2 == null) {

                    //if we reached our target, drop it.
                    if (ant.Equals(ant.Target)) {
                        ant.Target = null;
                        ant.Route = null;
                    }

                    //if an ant in not in attack mode, avoid getting killed by not taking this route.
                    //we need to check this each turn because our routes are calculated only one time
                    //and enemy ants may be moved.
                    if (ant.Route != null && ant.Route.Count > 1) {
                        if (state.GetIsAttackable(ant.Route[1]) && ant.Mode != AntMode.Attack) {
                            ant.Route = null;
                        }
                    }

                    //if an ant has no target or waited for too long, get a new target
                    if (ant.Target == null || ant.WaitTime > 2) {
                        decision.SetTarget(ant, state);
                        ant.Route = null;
                    }

//.........这里部分代码省略.........
开发者ID:CPutz,项目名称:KIPracticum1,代码行数:101,代码来源:MyBot.cs

示例12: FindPath

    // Returns a list of tiles that form the shortest path between start and dest
    public static List<Location> FindPath(Location start, Location dest, IGameState state)
    {
        if (start.Equals(dest) || !state.GetIsPassable(dest))
            return null;

        HashSet<Location> closed = new HashSet<Location>();
        Dictionary<Location, PathfindNode> locToNode = new Dictionary<Location, PathfindNode>();
        List<PathfindNode> open = new List<PathfindNode>();

        List<Location> reachable;

        PathfindNode first = new PathfindNode(start, null, dest, state);
        open.Add(first);
        locToNode.Add(first.Position, first);

        // Repeat until the destination node is reached
        PathfindNode last = null;
        while (open.Count > 0)
        {

            // Search the best available tile (lowest cost to reach from start, closest to dest)

            PathfindNode best = null;
            foreach (PathfindNode next in open)
            {
                if (best == null)
                    best = next;

                if (next.F < best.F)
                    best = next;
            }

            //PathfindNode best = open.Min;

            // Move to closed list
            open.Remove(best);
            locToNode.Remove(best.Position);
            closed.Add(best.Position);

            if (best.Position.Equals(dest)) // Destination added to closed list - almost done!
            {
                last = best;
                break;
            }

            // Find tiles adjacent to this tile
            reachable = GetNeighbours(best.Position, state);
            PathfindNode pfn;
            foreach (Location next in reachable)
            {
                if (!state.GetIsPassable(next)) // Check if tile is blocked
                    continue;

                if (closed.Contains(next))
                    continue;

                if(locToNode.ContainsKey(next))
                {
                    pfn = locToNode[next];
                    if (best.G + 1 < pfn.G)
                        pfn.Parent = best;
                }
                else{
                    pfn = new PathfindNode(next, best, dest, state);
                    open.Add(pfn);
                    locToNode.Add(next, pfn);
                }
            }
        }

        if (last == null)
            return null;

        // Trace the route from destination to start (using each node's parent property)
        List<PathfindNode> route = new List<PathfindNode>();
        while (last != first && last != null)
        {
            route.Add(last);
            last = last.Parent;
        }

        // Reverse route and convert to Points
        List<Location> path = new List<Location>();
        for (int i = route.Count - 1; i >= 0; i--)
        {
            path.Add(route[i].Position);
        }

        // Return the list of Points
        return path;
    }
开发者ID:Lapixx,项目名称:CS-UU-KI2,代码行数:92,代码来源:Pathfinding.cs

示例13: DoTurn

        public override void DoTurn(IGameState state)
        {
            var usedMoves = new HashSet<Location>();

            foreach (Ant ant in state.MyAnts)
            {
                int min = int.MaxValue;
                Location minLoc = ant;

                foreach (var point in state.FoodTiles)
                {
                    int ras = state.GetDistance(point, ant);
                    if (min > ras)
                    {
                        min = ras;
                        minLoc = point;
                    }
                }
                int x1 = ant.Col;
                int y1 = ant.Row;
                int x2 = minLoc.Col;
                int y2 = minLoc.Row;
                int dx = Math.Abs(x1-x2);
                int dy = Math.Abs(y1-y2);
                var direction = Direction.East;
                if (dx > 0)
                {
                    if (dx < state.Width - dx)
                        direction = GetDirectionX(x2 - x1);
                    else
                        direction = GetDirectionX(x1 - x2);
                }
                else if(dy > 0)
                {
                    if (dy < state.Height - dy)
                        direction = GetDirectionY(y2 - y1);
                    else
                        direction = GetDirectionY(y1 - y2);
                }

                Location newLoc = state.GetDestination(ant, direction);
                if (state.GetIsPassable(newLoc) && !usedMoves.Contains(newLoc))
                {
                    usedMoves.Add(newLoc);
                    IssueOrder(ant, direction);
                }
                /*for (int i = 0; i < 4; i++ )
                {
                    var direction = _directions[
                        _random.Next(4)];

                    Location newLoc = state.GetDestination(ant, direction);

                    if (state.GetIsPassable(newLoc) && !usedMoves.Contains(newLoc))
                    {
                        usedMoves.Add(newLoc);
                        IssueOrder(ant, direction);
                        break;
                    }

                }*/

                if (state.TimeRemaining < 10) break;
            }
        }
开发者ID:MichaelEk,项目名称:AIChallengeTraining,代码行数:65,代码来源:MyBot.cs

示例14: WalkThatWay

        // Local planning (for individual ant)
        public void WalkThatWay(Ant a, IGameState state)
        {
            if (heatMap.GetCell(a) > 0.1f)
                heatMap.UpdateCell(a, -0.1f);

            string key = LocationToKey(a);
            if (!currentTasks.ContainsKey(key))
            {
                if (state.MyAnts.Count / 8 > martinSheen.Count && timRobbins.Count > 0)
                {
                    Location martin = timRobbins[timRobbins.Count - 1];
                    timRobbins.RemoveAt(timRobbins.Count - 1);
                    martinSheen.Add(martin);
                    currentTasks.Add(key, new CurrentTask(Task.Guaaard, martin));
                }
                else if (state.MyAnts.Count >= armySize)
                {
                    return;
                }
                else
                {
                    LogShit("Shitjeweet.txt", currentStep + " added or something youknowyourself");
                    currentTasks.Add(key, new CurrentTask(Task.Roaming, a));
                }
            }

            CurrentTask task = currentTasks[key];
            task.from = a;
            task.resolved = false;

            if (task.task != Task.Terminating && task.task != Task.Guaaard)
            {
                foreach (Location e in theirHills)
                {
                    if (state.GetDistance(a, e) <= raidRadius)
                    {
                        task.hill = e;
                        task.task = Task.Terminating;
                        break;
                    }
                }
            }

            if (task.task == Task.Terminating)
            {
                if (task.hill.Equals(a))
                {
                    theirHills.Remove(task.hill);
                    heatMap.ResetCell(task.hill);
                }
                if (!theirHills.Contains(task.hill))
                {
                    task.task = Task.Roaming;
                    task.roam = a;
                }
            }

            if (task.task == Task.Dinner)
            {
                if (task.food.Equals(a) || (state[task.food.Row, task.food.Col] != Tile.Food && state.GetIsVisible(task.food)))
                {
                    task.task = Task.Roaming;
                    yummies.Remove(task.food);
                }
            }

            if (task.task == Task.Roaming)
            {

                Location f = SearchFood(a, state);
                if (f != null)
                {
                    task.food = f;
                    task.task = Task.Dinner;
                    yummies.Add(f);
                }

                if (task.roam.Equals(a) || !state.GetIsPassable(task.roam) || state.GetDistance(a, task.roam) <= arrivalRadius)
                {
                    heatMap.UpdateCell(task.roam, -5f);
                    task.roam = GetNewDestination(a, state);
                    if (task.roam == null)
                    {
                        task.to = task.from;
                        return;
                    }
                }
            }

            List<Location> avoid = new List<Location>();
            avoid.AddRange(state.MyHills);
            avoid.AddRange(martinSheen);
            if (task.task == Task.Guaaard)
                avoid.Remove(task.roam);

            Location tgt = null;
            switch (task.task)
            {
                case Task.Roaming: tgt = task.roam; break;
//.........这里部分代码省略.........
开发者ID:Lapixx,项目名称:CS-UU-KI1,代码行数:101,代码来源:MyBot.cs

示例15: Init

        // Initialise at first step
        public void Init(IGameState state)
        {
            random = new Random();
            currentTasks = new Dictionary<string, CurrentTask>();
            nextTasks = new Dictionary<string, CurrentTask>();
            myHills = new List<Location>(state.MyHills);
            theirHills = new List<Location>();
            yummies = new List<Location>();
            timRobbins = new List<Location>();
            martinSheen = new List<Location>();
            viewRadius = (int)Math.Sqrt(state.ViewRadius2);
            heatMap = new HeatMap(viewRadius, state);

            influenceMaps = new LayeredInfluenceMap(state);
            influenceMaps["Enemies"] = new InfluenceMap(state, 4, 1);
            influenceMaps["Friends"] = new InfluenceMap(state, 1, 1);

            foreach (Location h in myHills)
            {
                heatMap.UpdateCell(h, -5f);

                Location tim;
                tim = h + new Location(-1, -1);
                if (state.GetIsPassable(tim))
                    timRobbins.Add(tim);

                tim = h + new Location(-1, 1);
                if (state.GetIsPassable(tim))
                    timRobbins.Add(tim);

                tim = h + new Location(1, -1);
                if (state.GetIsPassable(tim))
                    timRobbins.Add(tim);

                tim = h + new Location(1, 1);
                if (state.GetIsPassable(tim))
                    timRobbins.Add(tim);
            }
        }
开发者ID:Lapixx,项目名称:CS-UU-KI1,代码行数:40,代码来源:MyBot.cs


注:本文中的IGameState.GetIsPassable方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。