示例#1
0
void GameMap::dig( const Index2& center )
{
	m_objects[center.first][center.second]->checkDig(m_pPlayer);

	for (auto x : getSurrounding(center, 2))
	{
		m_objects[x.first][x.second]->checkDig(m_pPlayer);
	}
}
示例#2
0
bool GameMap::onEffectMap()
{
	Return_False_If(m_bUsingMap);

	Index2 pos = pointToIndex2(m_pPlayer->getPosition());
	vector<Index2> surround = getSurrounding(pos, 2);
	for (Index2& x : surround)
	{
		bool ret = m_objects[x.first][x.second]->onEffectMap(true);
		m_bUsingMap = ret||m_bUsingMap;
	}
	return m_bUsingMap;
}
示例#3
0
void Labyrinth::markPosition(int x, int y) {
    if(lab.at(y).at(x) == ' ') {
        // Check if corner
        std::map<char, char> surr = getSurrounding(x, y);
        if((surr['s'] == '#' && surr['w'] == '#' && surr['e'] == '#') ||
           (surr['n'] == '#' && surr['w'] == '#' && surr['e'] == '#') ||
           (surr['n'] == '#' && surr['s'] == '#' && surr['e'] == '#') ||
           (surr['n'] == '#' && surr['w'] == '#' && surr['s'] == '#')) {
               lab.at(y).at(x) = 'y';
        } else
           lab.at(y).at(x) = 'x';
    } else {
        lab.at(y).at(x) += 1;
    }
}
示例#4
0
void World::generateGeneric(noise::module::RidgedMulti ridged,
	noise::module::Perlin perlin, noise::module::Perlin perlin2)
{
	//Climate generation

	sf::Image clim = sf::Image();
	clim.create(width, height);

	ridged.SetFrequency(4.5);
	ridged.SetLacunarity(1.0);

	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{

			unsigned int val = 0;
			if (y > height / 2)
			{
				val = height - y;
			}
			else
			{
				val = y;
			}



			val *= 2;

			clim.setPixel(x, y, sf::Color(val, val, val, 255));
		}
	}

	//Add some noise
	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{


			unsigned int val = clim.getPixel(x, y).r;

			double dval = ridged.GetValue(x, y, 24.53) * 5.0;
			val = val + dval;

	
			clim.setPixel(x, y, sf::Color(val, val, val, 255));
		}
	}

	//-----------------------------------------------
	//Rainfall

	//Every sea tile creates rainfall, it moves right until it mets a tile
	//higher than 1.4 sealevel

	//Basically, for each x we will check until we meet a square and cut rainfall

	sf::Image rain = sf::Image();
	rain.create(width, height, sf::Color::White);


	for (int y = 0; y < height; y++)
	{
		int count = 0;
		for (int x = 0; x < width; x++)
		{
			if (count <= 0)
			{
				if (getSurrounding(heightmap, x, y, 2) <= 3 && rand() % 1000 >= 500)
				{
					count = 80;
				}
				rain.setPixel(x, y, sf::Color(255 - count, 255 - count, 255 - count));
			}
			else
			{
				if (heightmap.getPixel(x, y).r >= seaLevel * (1.4))
				{
					count += 60;
				}
				count--;
				rain.setPixel(x, y, sf::Color(255 - count, 255 - count, 255 - count));
				
			}

			if (rand() % 1000 >= 700)
			{
				sf::Uint8 val = rain.getPixel(x, y).r;
				val /= 2;

				rain.setPixel(x, y, sf::Color(val, val, val));
			}
		}
	}

	//Generate shores & beaches (basic cellular automata)

	sf::Image outim = heightmap;

	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{

			//Lone pixels may get deleted
			if (getSurrounding(heightmap, x, y) <= 1)
			{
				if (rand() % 1000 >= 250)
				{
					heightmap.setPixel(x, y, sf::Color::Black);
				}
			}

			//If a pixel is not fully surrounded its beach
			if (getSurrounding(heightmap, x, y) <= 3 && getSurrounding(heightmap, x, y) >= 1)
			{
				outim.setPixel(x, y, sf::Color(seaLevel + 1, seaLevel + 1, seaLevel + 1));
			}

			//If a pixel is closer than 3 pixels to something then it's shore
			if (getSurrounding(heightmap, x, y, 4) >= 1 && heightmap.getPixel(x, y).r <= seaLevel)
			{
				outim.setPixel(x, y, sf::Color(seaLevel - 50, seaLevel - 50, seaLevel - 50));
			}


		}
	}
	heightmap = outim;


	//Generate biome map
	//BY RGB 
	//128 164 177  -  Ocean (elev <= seaLevel)
	//187 223 237  -  Shore (elev >= 25 && elev <= seaLevel)
	//213 201 160  -  Beach (elev == seaLevel + 1)
	//--------------------------------------------------------
	//130 160 109  -  Grassland (med temp, med rain, med< height)
	//139 196 131  -  Rain (-high temp, good rain, med< height)
	//198 237 198  -  Tundra (low temp, any rain, med< height)
	//201 190 153  -  Desert (>high temp, low rain, med< height)
	//235 235 235  -  Mountain (any temp, any rain, high height)
	//196 220 130  -  Savanna (high temp, low rain, med height)
	//136 191 106  -  Plains (everything else)
	//255 255 255  -  Pole
	//OTHER: Plains

	sf::Image biome = sf::Image();
	biome.create(width, height, sf::Color(136, 191, 106));

	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{
			if (y <= (polarCap + rand() % polarCapRand - (polarCapRand / 2)) ||
				y >= height - (polarCap + rand() % polarCapRand - (polarCapRand / 2)))
			{
				biome.setPixel(x, y, sf::Color(255, 255, 255));
			}
			else if (heightmap.getPixel(x, y).r <= seaLevel)
			{
				if (heightmap.getPixel(x, y).r >= 25)
				{
					//Shore
					biome.setPixel(x, y, sf::Color(187, 223, 237));
				}
				else
				{
					//Ocean
					biome.setPixel(x, y, sf::Color(128, 164, 177));
				}
			}
			else
			{
				if (heightmap.getPixel(x, y).r == seaLevel + 1)
				{
					//Shore
					biome.setPixel(x, y, sf::Color(213, 201, 160));
				}
				else
				{
					//Forest
					if (heightmap.getPixel(x, y).r <= 230)
					{
						if (rain.getPixel(x, y).r >= 80 && rain.getPixel(x, y).r <= 210)
						{
							if (clim.getPixel(x, y).r >= 70 && clim.getPixel(x, y).r <= 90)
							{
								biome.setPixel(x, y, sf::Color(130, 160, 109));
							}
						}
						//Jungle
						else if (rain.getPixel(x, y).r >= 170)
						{
							if (clim.getPixel(x, y).r <= 120)
							{
								biome.setPixel(x, y, sf::Color(139, 196, 131));
							}
							else
							{
								//Desert otherwise
								biome.setPixel(x, y, sf::Color(201, 190, 153));
							}
						}
						else if (rain.getPixel(x, y).r <= 170)
						{
							//Desert
							if (clim.getPixel(x, y).r >= 140)
							{
								biome.setPixel(x, y, sf::Color(201, 190, 153));
							}

							//Savanna
							if (clim.getPixel(x, y).r >= 50)
							{
								biome.setPixel(x, y, sf::Color(196, 220, 130));
							}
						}
					}
					else if (heightmap.getPixel(x, y).r >= 245)
					{
						//Mountain 100%
						biome.setPixel(x, y, sf::Color(235, 235, 235));
					}

					//Tundra
					if (clim.getPixel(x, y).r <= 20)
					{
						biome.setPixel(x, y, sf::Color(198, 237, 198));
					}


				}
			}
		}
	}



	//Strategic Resource distribution generation
	//FOREST: GREEN CHANNEL
	//MINERAL: BLUE CHANNEL
	//PETROL: RED CHANNEL
	//URANIUM: ALPHA CHANNEL
	//If more are to be added create another image

	sf::Image strat = sf::Image();
	strat.create(width, height, sf::Color::Black);


	perlin.SetLacunarity(rand() % 12);
	perlin.SetFrequency(rand() % 12 + 3);

	perlin2.SetLacunarity(rand() % 6);
	perlin2.SetFrequency(rand() % 5 + 2);

	ridged.SetFrequency(rand() % 5 + 2);
	ridged.SetLacunarity(rand() % 10 + 4);


	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{
			//FOREST & MINERALS follow perlin distributions
			double dX = (double)x / detail;
			double dY = (double)y / detail;

			double valPd = perlin.GetValue(dX, dY, 12.0);
			unsigned int valP = ((valPd + 1) / 2) * 255;

			double valRd = ridged.GetValue(dX, dY, 5.0);
			unsigned int valR = ((valRd + 1) / 2) * 255;

			double valPPd = perlin2.GetValue(dX + seed, dY + seed, 54.0);
			unsigned int valPP = ((valPPd + 1) / 2) * 255;

			if (heightmap.getPixel(x, y).r >= seaLevel)
			{

				sf::Color c = sf::Color((valPP + valRd / 2), valP, valPP, 255);

				strat.setPixel(x, y, c);
			}
		}
	}

	//Generate height data map 
	//0, 0, 0         -  Normal Land
	//128, 128, 128   -  Hill Land
	//255, 255, 255   -  Mountain Land

	sf::Image elev = sf::Image();
	elev.create(width, height);

	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{
			unsigned int val = heightmap.getPixel(x, y).r;
			if (val >= 230 && val <= 240) 
			{
				elev.setPixel(x, y, sf::Color(128, 128, 128));
			}
			else if (val >= 240)
			{
				elev.setPixel(x, y, sf::Color(255, 255, 255));
			}
			else
			{
				elev.setPixel(x, y, sf::Color(0, 0, 0));
			}
		}
	}

	//Run rivers
	std::cout << "Running rivers!" << std::endl;

	sf::Clock abortClock = sf::Clock();

	sf::Image tmpRiver = sf::Image();
	tmpRiver.create(width, height);

	int riversPlaced = 0;
	while (riversPlaced < rivers)
	{
		bool valid = false;
		int x = rand() % width;
		int y = rand() % (height - polarCap * 2) + polarCap * 2;
		int length = rand() % width / 1.5;
		//Get random location on map
		while (!valid)
		{
			if (abortClock.getElapsedTime().asSeconds() >= 2)
			{
				std::cout << "River generation abort (timeout)!";
				valid = true;
			}
			x = rand() % width;
			y = rand() % (height - polarCap * 2) + polarCap * 2;
			if (getSurrounding(heightmap, 
				x, y, 4) >= 9 && heightmap.getPixel(x, y).r <= seaLevel)
			{
				valid = true;
			}
		}
		

		x %= width;
		y %= height;

		int placedTiles = 0;
		int xstraight = 0;
		int ystraight = 0;

		bool xpos = false;
		bool ypos = false;
		while (placedTiles < length)
		{
			bool valid = false;
			while (!valid)
			{

				if (abortClock.getElapsedTime().asSeconds() >= 2)
				{
					std::cout << "River generation abort (timeout)!";
					valid = true;
				}

				//Drunk walk algorithm


				if (xstraight >= length / 2 || rand() % 1000 >= 990)
				{
					xpos = !xpos;
					xstraight = 0;
				}
				else
				{
					xstraight++;
				}

				if (ystraight >= length / 3 || rand() % 1000 >= 999)
				{
					ypos = !ypos;
					ystraight = 0;
				}
				else
				{
					xstraight++;
				}

				if (xpos && ypos)
				{
					if (rand() % 1000 >= 500)
					{
						xpos = false;
					}
					else
					{
						ypos = false;
					}
				}

				if (!xpos && !ypos)
				{
					if (rand() % 1000 >= 500)
					{
						xpos = true;
					}
					else
					{
						ypos = true;
					}
				}


				if (xpos)
				{
					x += rand() % 2 - 1;
				}
				else
				{
					x -= rand() % 2 - 1;
				}


			

				if (ypos)
				{
					y += rand() % 2 - 1;
				}
				else
				{
					y -= rand() % 2 - 1;
				}


				if (x < 0)
				{
					x = width;
				}

				if (y < 0)
				{
					y = height;
				}

				x %= width;
				y %= height;

				if (heightmap.getPixel(x, y).r >= seaLevel
					&& getSurrounding(tmpRiver, x, y, 2) <= 1)
				{
					valid = true;
				}
			}


			heightmap.setPixel(x, y, sf::Color(0, 0, 0));
			elev.setPixel(x, y, sf::Color(15, 15, 15));
			tmpRiver.setPixel(x, y, sf::Color(255, 255, 255));

			placedTiles++;
		}
		riversPlaced++;

	}

	//Make rivers all orthogonal
	for (int x = 1; x < width - 1; x++)
	{
		for (int y = 1; y < height - 1; y++)
		{
			if (tmpRiver.getPixel(x, y).r >= 5)
			{
				if (tmpRiver.getPixel(x+1, y+1).r >= 5)
				{
					if (tmpRiver.getPixel(x + 1, y).r <= 5)
					{
						elev.setPixel(x + 1, y, sf::Color(15, 15, 15));
					}
					else
					{
						if (tmpRiver.getPixel(x, y + 1).r <= 5)
						{
							elev.setPixel(x, y + 1, sf::Color(15, 15, 15));
						}
					}
				}
				if (tmpRiver.getPixel(x+1, y-1).r >= 5)
				{
					//RightUp
					if (tmpRiver.getPixel(x + 1, y).r <= 5)
					{
						elev.setPixel(x + 1, y, sf::Color(15, 15, 15));
					}
					else
					{
						if (tmpRiver.getPixel(x, y + 1).r <= 5)
						{
							elev.setPixel(x, y + 1, sf::Color(15, 15, 15));
						}
					}
				}
				if (tmpRiver.getPixel(x-1, y+1).r >= 5)
				{
					//LeftDown
					if (tmpRiver.getPixel(x - 1, y).r <= 5)
					{
						elev.setPixel(x - 1, y, sf::Color(15, 15, 15));
					}
					else
					{
						if (tmpRiver.getPixel(x, y - 1).r <= 5)
						{
							elev.setPixel(x, y - 1, sf::Color(15, 15, 15));
						}
					}
				}
				if (tmpRiver.getPixel(x-1, y-1).r >= 5)
				{
					//LeftUp
					if (tmpRiver.getPixel(x - 1, y).r <= 5)
					{
						elev.setPixel(x - 1, y, sf::Color(15, 15, 15));
					}
					else
					{
						if (tmpRiver.getPixel(x, y - 1).r <= 5)
						{
							elev.setPixel(x, y - 1, sf::Color(15, 15, 15));
						}
					}
				}
			}
		}
	}

	//Make rivers 1 tile wide
	for (int x = 1; x < width - 1; x++)
	{
		for (int y = 1; y < height - 1; y++)
		{
			if (getSurrounding(tmpRiver, x, y, 2) >= 3)
			{
				elev.setPixel(x, y, sf::Color(0, 0, 0));
				tmpRiver.setPixel(x, y, sf::Color(0, 0, 0));
			}
		}
	}

	this->rainfall = rain;
	this->climate = clim;
	this->resources = strat;
	this->biome = biome;
	this->elev = elev;


	moveCost = sf::Image();
	moveCost.create(width, height);

	//Generate move costs (from resource and elev)
	//Load data from json
	JSONLoader loader = JSONLoader();
	Json::Value root;

	loader.loadFile("res/data/tilesettings.json", root, false);

	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{
			int val = 0;
			if (resources.getPixel(x, y).g >= root["forestThresold"].asInt())
			{
				val += root["forestCost"].asInt();
			}

			if (elev.getPixel(x, y).r >= 128)
			{
				val += root["hillCost"].asInt();
			}

			if (elev.getPixel(x, y).r >= 255)
			{
				val += root["mountainCost"].asInt();
			}

			if (heightmap.getPixel(x, y).r <= seaLevel + 2)
			{
				moveCost.setPixel(x, y, sf::Color(0, 0, 255));
			}
			else
			{
				moveCost.setPixel(x, y, sf::Color(val, val, val));
			}
		}
	}

}
    void occupancyGridCallback(const nav_msgs::OccupancyGrid occupancyGrid) {
        if(!onTheMove) {
            onTheMove = true;
            grid = occupancyGrid;
            float resolution = occupancyGrid.info.resolution;
            tf::TransformListener listener(ros::Duration(10));
            //transform object storing our robot's position
            tf::StampedTransform transform;
            try {
                ros::Time now = ros::Time::now();
                geometry_msgs::PointStamped base_point;
                listener.waitForTransform("/world", "/base_link", now, ros::Duration(0.5));
                listener.lookupTransform("/world", "/base_link", ros::Time(0), transform);
                double x = transform.getOrigin().x();
                double y = transform.getOrigin().y();

//                ROS_INFO_STREAM("STARTPOSITION X: " <<x<<" STARTPOSITION Y: " <<y);
                robot_pos[0] = (int) ((x / resolution) + (int)(occupancyGrid.info.width/2));
                robot_pos[1] = (int) ((y / resolution) + (int)(occupancyGrid.info.height/2));
//                ROS_INFO("X = %i , Y = %i", robot_pos[0], robot_pos[1]);
//                ROS_INFO("LETS GET THE FRONTIERS");
                std::vector<std::vector<int> > frontiersList = frontierDetection(occupancyGrid, robot_pos[0], robot_pos[1]);
//                ROS_INFO("FRONIERS SERVED!");

                x = robotX;
                y = robotY;

                int num_frontier_cells = 0;

                for(unsigned int i = 0 ; i < frontiersList.size() ; i++ ) {
                    for(unsigned int j = 0 ; j < frontiersList[i].size() ; j++) {
                        num_frontier_cells++;
                    }
                }

//                ROS_INFO("%i frontier cells found",num_frontier_cells);
                double goalX = 0;
                double goalY = 0;
                frontier_cloud.points.resize(0);
                frontier_cloud.points.resize(num_frontier_cells);
                int frontierIndex = 0;
                //arbitrary value which is always higher than any distance found
                double minDist = 40000.0;
                //represents the closest frontier
                std::vector <int> closestFrontier;

                int fewestObstacles = 999999;

//                std::vector<std::vector<int> > blocked;

                //fill frontier cloud for publishing and calculate frontier closest to robot base
                for(unsigned int i = 0 ; i < frontiersList.size() ; i++ ) {
                    for(unsigned int j = 0 ; j < frontiersList[i].size() ; j++) {
                        double fX = (frontiersList[i][j] - (int)(occupancyGrid.info.width/2)) * occupancyGrid.info.resolution;
                        frontier_cloud.points[frontierIndex].x = fX;
                        double fY = (frontiersList[i][j+1] - (int)(occupancyGrid.info.height/2)) * occupancyGrid.info.resolution;


                        frontier_cloud.points[frontierIndex].y = fY;
                        frontier_cloud.points[frontierIndex].z = 0;
                        frontierIndex++;
                        j++;



                        if(!isBlocked(fX, fY))
                        {
                        double gridX = (fX / occupancyGrid.info.resolution) + (int)(occupancyGrid.info.width/2);
                        double gridY = (fY / occupancyGrid.info.resolution) + (int)(occupancyGrid.info.height/2);

                        // Get neighbors
                        std::vector<int> neighbors = getSurrounding(occupancyGrid, gridX, gridY, 20);

                        // Count obstacles
                        int obstacles = 0;
                        for (int a = 0; a < neighbors.size(); a += 2) {
                            std::vector<int> current;
                            current.push_back(neighbors[a]);
                            current.push_back(neighbors[a + 1]);
                            if (getMapValue(occupancyGrid, current[0], current[1]) > 0) {
                                obstacles++;
                            }
                        }

                        double distanceToRobot = sqrt((fX-x)*(fX-x)+(fY-y)*(fY-y));
                        double distanceToLastGoal = 5*sqrt((fX-prevGoalX)*(fX-prevGoalX)+(fY-prevGoalY)*(fY-prevGoalY));


                        obstacles += distanceToRobot+distanceToLastGoal;

                        if(obstacles < fewestObstacles)
                        {
                            fewestObstacles = obstacles;
                            double randomX = 1./(rand() % 100 + 1);
                            double randomY = 1./(rand() % 100 + 1);
                            double randomRange = 1;
                            goalX = fX;//-randomRange/2+randomRange*randomX;
                            goalY = fY;//-randomRange/2+randomRange*randomY;

                            std::cout << "distanceToRobot = " << distanceToRobot << std::endl;
                            std::cout << "distanceToLastGoal = " << distanceToLastGoal << std::endl;
                            std::cout << "obstacles = " << obstacles << std::endl;
                        }

//                        if(distance < minDist && distance > 2) {
//                            closestFrontier = frontiersList[i];
//                            minDist = distance;
//                            goalX = fX;
//                            goalY = fY;
//                        }
                        }
                    }
                }
                if(goalX == prevGoalX && goalY == prevGoalY)
                    sameCounter++;
                else
                    sameCounter = 0;
                if(sameCounter > 0)
                {
                    std::vector<double> error;
                    error.push_back(goalX);
                    error.push_back(goalY);
                    blocked.push_back(error);
                }
                prevGoalX = goalX;
                prevGoalY = goalY;
//                ROS_INFO_STREAM();
                // find a reachable goal position
                // select a target cell surrounded by free space only
//                double gridX = (goalX / occupancyGrid.info.resolution) + (int)(occupancyGrid.info.width/2);
//                double gridY = (goalY / occupancyGrid.info.resolution) + (int)(occupancyGrid.info.height/2);
//                std::vector<int> neighbors = getSurrounding(occupancyGrid, gridX, gridY, 50);
//                if(!isFree(neighbors, occupancyGrid)) {
//                    for (int i = 0; i < neighbors.size(); i += 2) {
//                        std::vector<int> current;
//                        current.push_back(neighbors[i]);
//                        current.push_back(neighbors[i + 1]);
//                        std::vector<int> currentNeighbors = getSurrounding(occupancyGrid, current[0], current[1], 10);
//                        if(isFree(currentNeighbors, occupancyGrid)) {
//                            goalX = (current[0] - (int)(occupancyGrid.info.width/2)) * occupancyGrid.info.resolution;
//                            goalY = (current[1] - (int)(occupancyGrid.info.width/2)) * occupancyGrid.info.resolution;
//                            break;
//                        }
//                    }
//                }

                next_frontier.points.resize(1);
                next_frontier.points[0].x = goalX;
                next_frontier.points[0].y = goalY;
                next_frontier.points[0].z = 0;

                frontier_publisher.publish(frontier_cloud);
                next_frontier_publisher.publish(next_frontier);
//                ROS_INFO("published cloud!");
                run(goalX,goalY);

            } catch (tf::TransformException& ex) {
                ROS_ERROR(
                            "Received an exception trying to transform a point from \"map\" to \"odom\": %s",
                            ex.what());
            }
        }
    }
示例#6
0
void GameMapRecrusive::makeMap(int mLevel, int vLevel)
{
    m_mLevel = mLevel;
    m_vLevel = vLevel;

    //10*20 -> 20*20 -> 20*30 -> 30*30
    m_mapRows = 10* (vLevel/2+1);
    m_mapCols = 20+10*vLevel/2;
    m_mapCols = min(50, m_mapCols);

    m_roomSize = 5;//5-vLevel/3;//3 + vLevel/2;
    m_roomSize = max(3, m_roomSize);

    m_mineCount = 5 + 20*vLevel;
    m_coinCount = 5+vLevel;// + 10*vLevel;
    m_propCount = 5+vLevel;// + 10*vLevel;
// 	m_hallMin = max(2, 5 - vLevel/2);
    //
    m_objects.resize(m_mapRows);

    for(int r=0; r<m_mapRows; ++r)
    {
        m_objects[r].resize(m_mapCols);

        for(int c=0; c<m_mapCols; ++c)
        {
            MapCell* cell = MapCell::create();
            cell->setPosition(Point(c*m_tw, r*m_th) + Point(0, m_th) /*+ m_border*/);
            cell->setLocalZOrder((m_mapRows-r-1)*m_mapCols + c);
            addChild(cell);
            m_objects[r][c] = cell;
        }
    }

    //
    this->setContentSize(Size(m_mapCols*m_tw/*+m_border.width*2*/, m_mapRows*m_th/*+m_border.height*2*/));
    generate(0, 0, m_mapRows, m_mapCols);

    while(m_mineCount>0)
    {
        int r = rand()% (m_mapRows-2)+1;
        int c = rand()% (m_mapCols-2)+1;
        setTrap(r, c);
    }

    while(m_coinCount>0)
    {
        int r = rand()% (m_mapRows-2)+1;
        int c = rand()% (m_mapCols-2)+1;
        setCoin(r, c);
    }

    while(m_propCount > 0)
    {
        int r = rand()% (m_mapRows-2)+1;
        int c = rand()% (m_mapCols-2)+1;
        setProp(r, c);
    }

	for (int r = 0; r < m_mapRows; ++r)
	{
		for (int j=0; j < m_mapCols; ++j)
		{
			if (m_objects[r][j]->empty())
			{
				if (rand()%100<70)
				{
					setSoil(r, j, false);
				}
			}
		}
	}
    //
    const Index2 pos(rand()%m_mapRows,0);
    m_pPlayer = Player::create();
    m_pPlayer->setPosition(index2ToPoint(pos)+Point(m_tw/2, m_th/2));
    addChild(m_pPlayer, m_mapRows*m_mapCols+1);
    m_objects[pos.first][pos.second]->clear();

    for(auto x : getSurrounding(pos))
    {
        m_objects[x.first][x.second]->clear();
    }

    //
    ValueMap val;
    val["type"] = "LevelStair";
    const Index2 win(rand()%m_mapRows, m_mapCols-1);
    m_objects[win.first][win.second]->clear();
    m_objects[win.first][win.second]->pushObjBy(val);
}
示例#7
0
void GameMap::onClick( const Point& pt )
{
	m_pPlayer->hideTip();

	Index2 click = pointToIndex2(pt);
	Index2 player = pointToIndex2(m_pPlayer->getPosition());

	CCLOG("click(%d, %d)", click.first, click.second);
	Rect asdf = this->getBoundingBox();
	if (m_bUsingHoe)
	{
		vector<Index2> surround = getSurrounding( player, 2);
		for (Index2& x : surround)
		{
			m_objects[x.first][x.second]->onEffectHoe(false, click==x);
		}
		m_bUsingHoe = false;
		return;
	}
	//
	if (m_bUsingBomb)
	{
		vector<Index2> surround = getSurrounding(player, 2);
		for (Index2& x : surround)
		{
			m_objects[x.first][x.second]->onEffectBomb(false, click==x);
		}
		m_bUsingBomb = false;
		return;
	}
	//
	if (m_bUsingMap)
	{
		m_bUsingMap = false;
		vector<Index2> surround = getSurrounding(player, 2);
		for (Index2& x : surround)
		{
			m_objects[x.first][x.second]->onEffectMap(false);
		}
	}

	Return_If(player == click);
	
	//
	if (m_curPath.empty())
	{
		m_restartPlayer = false;
		auto x = player;
		m_curPath = getPath( x, click );
		if (m_curPath.empty())
		{
			m_pPlayer->showTip("unknown.png");
		}
		else
		{
			stepPlayer();
		}
	}
	else
	{
		m_restartPlayer = true;
		m_playerTarget = pt;
	}
}
示例#8
0
list<GameMap::Index2> GameMap::getPath( const Index2& from, const Index2& to )
{
	if (from==to || (to.first<0 || to.first>=m_objects.size() || to.second<0 || to.second>=m_objects[0].size()))
		return list<Index2>();

	struct AStarInfo
	{
		int g;
		int h;
		Index2 parent;
		int f(){ return g+h; }
		AStarInfo(int argg, int argh){
			g = argg;
			h = argh;
			parent.first = parent.second = -1;
		}
	};
	map<Index2, AStarInfo> opened;
	map<Index2, AStarInfo> closed;
	auto last_obj = opened.end();
	opened.insert( make_pair(from, AStarInfo(0,0)) );
	do
	{
		Break_If( opened.empty() );
		int min_cost = INT_MAX;
		Index2 curPos(-1,-1);
		AStarInfo curInfo(INT_MAX, 0);
		map<Index2, AStarInfo>::iterator cur;
		for (map<Index2, AStarInfo>::iterator it = opened.begin(); it != opened.end(); ++it)
		{
			if (it->second.f() < curInfo.f())
			{
				curPos = it->first;
				curInfo = it->second;
				cur = it;
			}
		}
		opened.erase(cur);
		closed.insert( make_pair(curPos, curInfo) );

		auto surround = getSurrounding(curPos, 1);
		for (auto it = surround.begin(); it != surround.end(); ++it)
		{
			MapCell* cell = m_objects[it->first][it->second];
			if ( *it == to )
			{
				AStarInfo info( curInfo.g+loss(curPos,*it), loss(*it, to) );
				info.parent = curPos;
				opened.insert( make_pair(*it, info) );
			}
			else if ( cell->getAStarCost()==INT_MAX || closed.find(*it)!=closed.end() )
			{
				//do nothing
			}
			else if ( opened.find(*it) == opened.end() )
			{
				AStarInfo info( curInfo.g+loss(curPos,*it), loss(*it, to) );
				info.parent = curPos;
				opened.insert( make_pair(*it, info) );
			}
			else//已经在开启列表中,检查新的路径是否更好
			{
				auto has = opened.find(*it);
				if (has->second.g > curInfo.g+loss(curPos,*it))
				{
					has->second.parent = curPos;
					has->second.g = curInfo.g+loss(curPos,*it);
				}
			}
		}
		
		last_obj = opened.find(to);
		if (last_obj != opened.end())
			break;

	} while (true);

	if (last_obj == opened.end())
	{
		return list<Index2>();
	}

	list<Index2> ret;
	ret.push_front( last_obj->first );
	auto path = closed.find( last_obj->second.parent );
	while (path != closed.end())
	{
		ret.push_front(path->first);
		path = closed.find( path->second.parent );
	}
	if (!ret.empty())
		ret.pop_front();

	if (ret.size() > 10)
	{
		ret.clear();
	}
	return ret;
}
示例#9
0
bool GameMap::initWithLevel( int mainLevel, int viceLevel )
{
	Return_False_If(!Node::init());

	this->makeMap(mainLevel, viceLevel);

	const int order = m_objects.size()*m_objects[0].size();
	const Size size = this->getContentSize();
	float x = 0;
	float up_height = 0;
	while (x<size.width)
	{
		Sprite* sp = Sprite::create("bound_up.png");
		sp->setPosition(x, size.height);
		sp->setAnchorPoint(Point(0,0));
		addChild(sp, order);

		x += sp->getContentSize().width;

		up_height = sp->getContentSize().height;
	}
	x = 0;
	float bottom_height = 0;
	while (x<size.width)
	{
		Sprite* sp = Sprite::create("bound_bottom.png");
		sp->setPosition(x, 0);
		sp->setAnchorPoint(Point(0,1));
		addChild(sp, order+1);

		x += sp->getContentSize().width;

		bottom_height = sp->getContentSize().height;
	}

	float y = -bottom_height;
	float left_width = 0;
	while (y<size.height)
	{
		Sprite* sp = Sprite::create("bound_left.png");
		sp->setPosition(0, y);
		sp->setAnchorPoint(Point(1,0));
		addChild(sp, order);

		left_width = sp->getContentSize().width;

		sp = Sprite::create("bound_left.png");
		sp->setAnchorPoint(Point(0,0));
		sp->setRotation(180);
		sp->setPosition(size.width+left_width, y+sp->getContentSize().height);
		addChild(sp, order);

		y += sp->getContentSize().height;
	}

	//init display number
	for (int r=0; r<m_objects.size(); ++r)
	{
		for (int c=0; c<m_objects[r].size(); ++c)
		{
			int mine_count = 0;
			for (auto&x : getSurrounding(Index2(r,c)))
			{
				if (m_objects[x.first][x.second]->isMine())
				{
					++mine_count;
				}
			}
			m_objects[ r ][ c ]->setSurroundMineCount(mine_count);
		}
	}

	CCAssert(NULL!=m_pPlayer, "");
	dig(pointToIndex2(m_pPlayer->getPosition()));

// 	Size size = this->getContentSize(); 
// 	-m_border.width, -m_border.height, size.width+m_border.width*2, size.height+m_border.height*2
	const float tool = toolbar->getContentSize().height*4/5;
	this->runAction( Follow::create(m_pPlayer, Rect(-left_width, -bottom_height-tool, size.width+left_width*2, size.height+up_height+bottom_height+tool)));
	return true;
}