예제 #1
0
        /// <summary>
        /// Try to drive one tile in a random direction.
        /// </summary>
        /// <param name="pos">Current position.</param>
        /// <param name="dirLast">Forbidden direction for movement (to prevent reversing).</param>
        /// <returns>Direction of movement, DIR2_INVALID is returned if not moved.</returns>
        private Direction2 tryGo(Position pos, Direction2 dirLast)
        {
            Direction2[] directions = new Direction2[4];

            // Find connections from current position.
            Direction2 dir   = Direction2.DIR2_NORTH;
            int        count = 0;
            int        i;

            for (i = 0; i < 4; i++)
            {
                if (dir != dirLast && roadTest(getTileFromMap(pos, dir, (ushort)MapTileCharacters.DIRT)))
                {
                    // found a road in an allowed direction
                    directions[i] = dir;
                    count++;
                }
                else
                {
                    directions[i] = Direction2.DIR2_INVALID;
                }

                dir = DirectionUtils.rotate90(dir);
            }

            if (count == 0)
            {
                // dead end
                return(Direction2.DIR2_INVALID);
            }

            // We have at least one way to go.

            if (count == 1)
            {
                // only one solution
                for (i = 0; i < 4; i++)
                {
                    if (directions[i] != Direction2.DIR2_INVALID)
                    {
                        return(directions[i]);
                    }
                }
            }

            // more than one choice, draw a random number.
            i = getRandom16() & 3;
            while (directions[i] == Direction2.DIR2_INVALID)
            {
                i = (i + 1) & 3;
            }
            return(directions[i]);
        }
예제 #2
0
        /// <summary>
        /// Try to drive to a destination.
        /// </summary>
        /// <param name="startPos">Starting position.</param>
        /// <param name="destZone">Zonetype to drive to.</param>
        /// <returns>Was drive succesful?</returns>
        bool tryDrive(Position startPos, ZoneType destZone)
        {
            Direction2 dirLast  = Direction2.DIR2_INVALID;
            Position   drivePos = new Position(startPos);

            /* Maximum distance to try */
            for (short dist = 0; dist < MAX_TRAFFIC_DISTANCE; dist++)
            {
                Direction2 dir = tryGo(drivePos, dirLast);
                if (dir != Direction2.DIR2_INVALID)
                {
                    // we found a road
                    drivePos.move(dir);
                    dirLast = DirectionUtils.rotate180(dir);

                    /* Save pos every other move.
                     * This also relates to
                     * Micropolis::trafficDensityMap::MAP_BLOCKSIZE
                     */
                    if ((dist & 1) != 0)
                    {
                        pushPos(drivePos);
                    }

                    if (driveDone(drivePos, destZone))
                    {
                        // if destination is reached
                        return(true); /* pass */
                    }
                }
                else
                {
                    if (curMapStackPointer > 0)
                    {
                        /* dead end, backup */
                        curMapStackPointer--;
                        dist += 3;
                    }
                    else
                    {
                        return(false); /* give up at start  */
                    }
                }
            }

            return(false); /* gone MAX_TRAFFIC_DISTANCE */
        }