예제 #1
0
int Arena::getNumberOfVisitedCells(Maze& m) {
    int count = 0;
    //for each cell in the maze
    for (int i = 0; i < m.getRows(); i++) {
        for (int j = 0; j < m.getCols(); j++) {
            //if cell has been visited, increase count
            if (m.getCell(i,j)->isVisited()) count++;
        }
    }
    return count;
}
예제 #2
0
double Arena::runSimulation(Maze& maze, Robot& r) {
	//reset maze
	maze.clearVisited();
	maze.clearValues();

	//set needed values after reset
	Cell* curCell = maze.getStartCell();
	robotOrientation = direction::SOUTH;
	unsigned int move;
	double score;

	//while the robot is not in the same cell facing the same direction
	while (!repeat(robotOrientation, curCell->getValue()) && !(curCell == maze.getEndCell())) {
		//set current cell to visited and update it's value
		curCell->setVisited();
		curCell->setValue(curCell->getValue() + robotOrientation);

		//send the robot the environment and get it's next move
		move = r.getMove(getEnv(robotOrientation, curCell));

		//perform next move

		//find rotation
		if (move == 3 || move == 7) {
			robotOrientation = Direction::left(robotOrientation);
		}
		else if (move == 2 || move == 6) {
			robotOrientation = Direction::opposite(robotOrientation);
		}
		else if (move == 1 || move == 5) {
			robotOrientation = Direction::right(robotOrientation);
		}
		else {
			//no rotation
		}

		//move forwards
		if (!curCell->hasWall(robotOrientation) && !curCell->hasEdge(robotOrientation)) {
			curCell = maze.getCell(curCell->getRow() + Direction::row(robotOrientation), curCell->getCol() + Direction::col(robotOrientation));
		}
	}

	//calculate score    
	//score is a 1 if the end has been reached, else it is 1 - (distance from end * 0.01)
	if (curCell == maze.getEndCell()) {
		score = 1.0;
	}
	else {
		score = (double)getNumberOfVisitedCells(maze) / (double)((double)maze.getRows() * (double)maze.getCols());
	}
	//return score
	return score;
}
예제 #3
0
void FindPathsFromXtoY::findAllThePaths(Maze& mazeT, Cell* startC, Cell* finalC)
{
	currentPath.pathVec.push_back(startC);
	currentPath.sizeOfPath++;
	startC->isCovered = true;

    if(startC->row == finalC->row &&
       startC->col == finalC->col)
    {
        allThePaths.push_back(currentPath);

        /*std::cout << "Current situation: " << std::endl;
        printAllThePaths();*/

        // currentPath.clear();
        // currentPath.pathVec.push_back(startCell);

        return;
    }



    for(int i = 0; i < 4; i++)
    {
        if(startC->row + xMoves[i] >= 0 &&
           startC->row + xMoves[i] < mazeT.getRows() &&
           startC->col + yMoves[i] >=0 &&
           startC->col + yMoves[i] < mazeT.getCols())
        {
            Cell* stepCell = mazeT.getCell(startC->row + xMoves[i], startC->col + yMoves[i]);
            if(stepCell &&
			   stepCell->isCovered == false &&
               stepCell->isOkayToPass())
            {
                // currentPath.push_back(stepCell);
                findAllThePaths(mazeT,stepCell,finalC);

				currentPath.pathVec.pop_back();
				currentPath.sizeOfPath--;
				stepCell->isCovered = false;
            }
        }
    }

    // startC->isCovered = false;
}
예제 #4
0
bool Computer::move_to_hero(Maze& level_map)
{
    Point lu_cornor;
    Point rd_cornor;
    Point point;
    unsigned step = 1;
    Point hero_position = position;
    unsigned hero_review = review;
    bool end = false;

    unsigned ** screen;
    unsigned size_screen = (review * 2 + 1);
    screen = new unsigned*[size_screen];
    for (auto i = 0U; i < size_screen; ++i)
        screen[i] = new unsigned[size_screen];
    for (auto i = 0U; i < size_screen; ++i)
        for (auto j = 0U; j < size_screen; ++j)
            screen[i][j] = 0;


    screen[hero_review][hero_review] = 1;
    while (step <= hero_review)
    {
        lu_cornor.x = hero_position.x - (step-1);
        lu_cornor.y = hero_position.y - (step-1);
        rd_cornor.x = hero_position.x + (step-1);
        rd_cornor.y = hero_position.y + (step-1);

        for (int i = lu_cornor.y; i <= rd_cornor.y; i++)
            for (int j = lu_cornor.x; j <= rd_cornor.x; j++)
            {
                if (!level_map.isExistance(i, j)) continue;
                point.y = i - hero_position.y + hero_review;
                point.x = j - hero_position.x + hero_review;
                if (screen[point.y][point.x] == step && level_map.getCell(i, j) != '#')
                {
                    if (level_map.isExistance(i - 1, j) && (point.y - 1 >= 0))
                        if (screen[point.y - 1][point.x] == 0)
                            screen[point.y - 1][point.x] = step + 1;

                    if (level_map.isExistance(i + 1, j) && ((unsigned)point.y + 1 < size_screen))
                        if (screen[point.y + 1][point.x] == 0)
                            screen[point.y + 1][point.x] = step + 1;

                    if (level_map.isExistance(i, j - 1) && (point.x - 1 >= 0))
                        if (screen[point.y][point.x  - 1] == 0)
                            screen[point.y][point.x - 1] = step + 1;

                    if (level_map.isExistance(i, j + 1) && ((unsigned)point.x + 1 < size_screen))
                        if (screen[point.y][point.x + 1] == 0)
                            screen[point.y][point.x + 1] = step + 1;
                }
            }

        step++;
    }

    for (auto i = 0U; i < size_screen; ++i)
    {
        for (auto j = 0U; j < size_screen; ++j)
        {
            if (screen[i][j] != 0 && level_map.getCell(i + position.y - review, j + position.x - review) == 'H')
            {
                point.y = i;
                point.x = j;

                for (auto it = screen[i][j] - 1; it > 1; --it)
                {
                    if ((unsigned)point.x + 1 < size_screen)
                    if (screen[point.y][point.x + 1] == it
                            && level_map.getCell(point.y + position.y - review, point.x + 1 + position.x - review) != '#')
                    {
                        point.x = point.x + 1;
                        point.y = point.y;
                        continue;
                    }

                    if (point.x - 1 >= 0)
                    if (screen[point.y][point.x - 1] == it
                            && level_map.getCell(point.y + position.y - review, point.x - 1 + position.x - review) != '#')
                    {
                        point.x = point.x - 1;
                        point.y = point.y;
                        continue;
                    }

                    if ((unsigned)point.y + 1 < size_screen)
                    if (screen[point.y + 1][point.x] == it
                            && level_map.getCell(point.y + 1 + position.y - review, point.x + position.x - review) != '#')
                    {
                        point.x = point.x;
                        point.y = point.y + 1;
                        continue;
                    }

                    if (point.y - 1 >= 0)
                    if (screen[point.y - 1][point.x] == it
                            && level_map.getCell(point.y - 1 + position.y - review, point.x + position.x - review) != '#')
                    {
                        point.x = point.x;
                        point.y = point.y - 1;
                        continue;
                    }
                }

                end = true;
                break;
            }
        }
        if (end) break;
    }

    if (end)
    {
        prev_position = position;
        position.x = position.x + point.x - review;
        position.y = position.y + point.y - review;
    }

    delete [] screen;

    if (end) return true;
    else return false;
}
예제 #5
0
bool Computer::movement(Maze level_map)
{
    const auto Q_POSSIBILITIES = 4U;
    SegmentDistribution distributed_move[Q_POSSIBILITIES];
    Point shift;
    Point temp;
    bool result, approval1 = false, approval2 = false, approval3 = false;
    unsigned left_boundary = 0;
    unsigned root_decision, decision;


    if(move_to_hero(level_map) == true) return true;

    //относительно героя компьютера
    if (prev_position == position)
    {
        shift.x = 0;
        shift.y = -1;
    }
    else
    {
    shift.x = position.x - prev_position.x;
    shift.y = position.y - prev_position.y;
    }

    distributed_move[0].probability = 70; // Смещение вперёд
    distributed_move[0].shift = shift;

    distributed_move[1].probability = 2; // Смещение назад
    distributed_move[1].shift.x = -shift.x;
    distributed_move[1].shift.y = -shift.y;

    distributed_move[2].probability = 14; // Смещение влево
    distributed_move[2].shift.x = shift.y;
    distributed_move[2].shift.y = -shift.x;

    distributed_move[3].probability = 14; // Смещение вправо
    distributed_move[3].shift.x = -shift.y;
    distributed_move[3].shift.y = shift.x;

    for (auto i = 0U; i < Q_POSSIBILITIES; ++i)
    {
        temp.x = position.x + distributed_move[i].shift.x;
        temp.y = position.y + distributed_move[i].shift.y;
        if (level_map.isExistance(temp.y, temp.x))
        {
            approval1 = level_map.getCell(temp.y, temp.x) != '#';
            approval2 = level_map.getCell(temp.y, temp.x) != 'E';
            approval3 = level_map.getCell(temp.y, temp.x) != 'M';
        }
        result = approval1 && approval2 && approval3;
        distributed_move[i].use = result;
        if (result == true) left_boundary += distributed_move[i].probability;
    }

    if (left_boundary == 0) return true;
    root_decision = rand() % left_boundary;

    for (auto i = 0U; i < Q_POSSIBILITIES; ++i)
    {
        if (!distributed_move[i].use) continue;
        if (root_decision < distributed_move[i].probability)
        {
            decision = i;
            break;
        }
        else
            root_decision -= distributed_move[i].probability;
    }

    prev_position = position;
    position.x += distributed_move[decision].shift.x;
    position.y += distributed_move[decision].shift.y;

    return true;
}
예제 #6
0
double Arena::runSimulation(Maze& maze, Robot& r, sf::RenderWindow& window) {
	sf::Font f;

	if (!f.loadFromFile("fonts/Oswald-Regular.ttf")) return 0;

	const int ROWS = maze.getRows();
	const int COLS = maze.getCols();
	const int CELL_SIZE = 30, OFFSET = 150;
	sf::RectangleShape rectangles[10][10];
	vector<sf::RectangleShape> lines;
	
	//text for display of info
	sf::Text bst;
	sf::Text med;
	sf::Text gen;
	//set fonts
	bst.setFont(f);
	med.setFont(f);
	gen.setFont(f);
	bst.setColor(sf::Color::Black);
	med.setColor(sf::Color::Black);
	gen.setColor(sf::Color::Black);
	//set sizes
	bst.setCharacterSize(24);
	med.setCharacterSize(24);
	gen.setCharacterSize(24);
	//set positions
	gen.setPosition(10, 10);
	bst.setPosition(10, 40);
	med.setPosition(10, 70);
	//set strings
	stringstream stream;
	stream.str("");
	string out;

	stream << generation;
	stream >> out;
	out = "Generation: " + out;
	gen.setString(out);

	stream.str(string());
	stream.clear();
	out.clear();
	stream << setprecision(2) << median;
	stream >> out;
	out = "Median Score: " + out;
	med.setString(out);

	stream.str(string());
	stream.clear();
	out.clear();
	stream << setprecision(2)  << best;
	stream >> out;
	out = "Best Score: " + out;
	bst.setString(out);
	
	//Cell used to find borders for the board spaces
	Cell* c;
	//populate rectangles as board spaces
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			//add board spaces, set color and position
			rectangles[i][j] = sf::RectangleShape(sf::Vector2f(CELL_SIZE, CELL_SIZE));
			rectangles[i][j].setFillColor(sf::Color::White);
			rectangles[i][j].setPosition((j * CELL_SIZE) + OFFSET, (i * CELL_SIZE) + OFFSET);
			
			//set cell to find borders and highlight end cell
			c = maze.getCell(i, j);
			if (c == maze.getEndCell()) rectangles[i][j].setFillColor(sf::Color::Blue);

			if (c->hasWall(direction::NORTH) || c->hasEdge(direction::NORTH)) {
				lines.push_back(sf::RectangleShape(sf::Vector2f(CELL_SIZE, 2)));
				lines[lines.size() - 1].setPosition(rectangles[i][j].getPosition());
				lines[lines.size() - 1].setFillColor(sf::Color::Black);
			}
			if (c->hasWall(direction::WEST) || c->hasEdge(direction::WEST)) {
				lines.push_back(sf::RectangleShape(sf::Vector2f(2, CELL_SIZE)));
				lines[lines.size() - 1].setPosition(rectangles[i][j].getPosition());
				lines[lines.size() - 1].setFillColor(sf::Color::Black);
			}
			if (c->hasWall(direction::SOUTH) || c->hasEdge(direction::SOUTH)) {
				lines.push_back(sf::RectangleShape(sf::Vector2f(CELL_SIZE, 2)));
				lines[lines.size() - 1].setPosition(rectangles[i][j].getPosition() + sf::Vector2f(0, CELL_SIZE));
				lines[lines.size() - 1].setFillColor(sf::Color::Black);
			}
			if (c->hasWall(direction::EAST) || c->hasEdge(direction::EAST)) {
				lines.push_back(sf::RectangleShape(sf::Vector2f(2, CELL_SIZE)));
				lines[lines.size() - 1].setPosition(rectangles[i][j].getPosition() + sf::Vector2f(CELL_SIZE, 0));
				lines[lines.size() - 1].setFillColor(sf::Color::Black);
			}
		}
	}
	
	//reset maze
	maze.clearVisited();
	maze.clearValues();

	//set needed values after reset
	Cell* curCell = maze.getStartCell();
	robotOrientation = direction::SOUTH;
	unsigned int move;
	double score;

	//clock for delays 
	sf::Clock clock;
	sf::Time delay = sf::milliseconds(50);

	//DRAW WINDOW INITIALLY WITH START CELL HIGHLIGHTED AS CURRENT
	window.clear(sf::Color::White);

	//highlight start cell
	rectangles[curCell->getRow()][curCell->getCol()].setFillColor(sf::Color::Green);

	//add cells
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			window.draw(rectangles[i][j]);
		}
	}

	//add borders
	for (unsigned int i = 0; i < lines.size(); i++) {
		window.draw(lines[i]);
	}

	//add information
	window.draw(gen);
	window.draw(bst);
	window.draw(med);

	window.display();

	//while the robot is not in the same cell facing the same direction
	while (!repeat(robotOrientation, curCell->getValue()) && !(curCell == maze.getEndCell())) {
		//set current cell to visited and update it's value
		curCell->setVisited();
		curCell->setValue(curCell->getValue() + robotOrientation);

		//send the robot the environment and get it's next move
		move = r.getMove(getEnv(robotOrientation, curCell));

		//perform next move

		//find rotation
		if (move == 3 || move == 7) {
			robotOrientation = Direction::left(robotOrientation);
		}
		else if (move == 2 || move == 6) {
			robotOrientation = Direction::opposite(robotOrientation);
		}
		else if (move == 1 || move == 5) {
			robotOrientation = Direction::right(robotOrientation);
		}
		else {
			//no rotation
		}

		//reset clock and hold for display
		clock.restart();
		while (clock.getElapsedTime() < delay) {}

		//HIGHLIGHT CURRENT CELL AS VISITED
		rectangles[curCell->getRow()][curCell->getCol()].setFillColor(sf::Color::Red);

		//move forwards
		if (!curCell->hasWall(robotOrientation) && !curCell->hasEdge(robotOrientation)) {
			curCell = maze.getCell(curCell->getRow() + Direction::row(robotOrientation), curCell->getCol() + Direction::col(robotOrientation));
		}

		//REDRAW WINDOW WITH UPDATED CELLS
		window.clear(sf::Color::White);

		//highlight current visiting cell
		rectangles[curCell->getRow()][curCell->getCol()].setFillColor(sf::Color::Green);

		//add cells
		for (int i = 0; i < ROWS; i++) {
			for (int j = 0; j < COLS; j++) {
				window.draw(rectangles[i][j]);
			}
		}

		//add borders
		for (unsigned int i = 0; i < lines.size(); i++) {
			window.draw(lines[i]);
		}

		sf::Event event;
		while (window.pollEvent(event))
		{
			// "close requested" event: we close the window
			if (event.type == sf::Event::Closed)
				return -1;
		} 

		//add information
		window.draw(gen);
		window.draw(bst);
		window.draw(med);

		window.display();

	}

	//calculate score    
	//score is a 1 if the end has been reached, else it is 1 - (distance from end * 0.01)
	if (curCell == maze.getEndCell()) {
		score = 1.0;
	}
	else {
		score = (double)getNumberOfVisitedCells(maze) / (double)((double)maze.getRows() * (double)maze.getCols());
	}
	//reset clock and hold for display
	clock.restart();
	while (clock.getElapsedTime() < sf::milliseconds(1000)) {}

	//return score
	return score;
	
}