void TicTacToe::play() {
  //player array is 0 indexed, so player 1 is at index 0. 
  int current_player = 0;
  //resets the board. 
  reset();
  printBoard();
  while(!isDone()) {
    std::cout << "Player " << current_player + 1 << "'s turn. \n";
    //getCoordinateFromUser is a BoardGame function
    Coordinate nextMove(getCoordinateFromUser());
    while(!isLegalMove(nextMove, player_list_[current_player].getSymbol())) {
      std::cout << "Invalid move. Please try again.\n";
      nextMove = getCoordinateFromUser();
    }
    doMove(nextMove, player_list_[current_player].getSymbol());
    printBoard();
    
    if(current_player == 0)
      current_player = 1;
    else
      current_player = 0;
  }
  results();
  
  
}
Exemple #2
0
void Walker::onWorkFinished()
{
    if(true)
    {
        nextMove(mTargetSeq);
    }
}
void mvZeroNextToTarget(searchData *d,int placeTarget)
{
  int placeZero = searchChar(&d->b, '0');
  int xd = (placeTarget % d->b.w) - (placeZero % d->b.w);
  int yd = (int)(placeTarget / d->b.w) - (int)(placeZero / d->b.w);
  char ways[4];
  int len;
  while(abs(xd) + abs(yd) > 0){
    len = nextMove(d->b, ways, d->preMove);
    char next;
    if(len == 1)
      next = ways[0];
    else
      next = chooseNext(ways, xd, yd, searchChar);
    move(&d->b, next);
    d->preMove = next;
    d->r.push_back(next);
    repairXdXy(next, &xd, &yd);
#ifdef DEBUG
  printf("ways=%s\n", ways);
  printBoard(d->b);
  getchar();
#endif
  }
}
Exemple #4
0
PositionStatus AbstractGame::getPositionStatus() {
  if(!POSITION_DEFINED()) {
    if(m_bricksOnBoard <= 1) {
      DEFINE_POSITION(m_bricksOnBoard == 0, m_bricksOnBoard);
    } else {

      bool winnerMoveFound = false;
      int  pliesToWin      = 30;
      int  pliesToLoose    = 0;
      for(Move m = firstMove(); m && !winnerMoveFound; m = nextMove(m)) {
        doMove(m);
        const PositionStatus status = getPositionStatus();
        if(IS_LOOSERSTATUS(status)) {
          winnerMoveFound = true;
          if(PLIESTOEND(status) < pliesToWin) {
            pliesToWin = PLIESTOEND(status);
          }
        } else if(!winnerMoveFound) {
          if(PLIESTOEND(status) > pliesToLoose) {
            pliesToLoose = PLIESTOEND(status);
          }
        }
        undoMove(m);
      }
      if(winnerMoveFound) {
        DEFINE_POSITION(true , pliesToWin   + 1);
      } else {
        DEFINE_POSITION(false, pliesToLoose + 1);
      }
    }
  }
  return m_statusTable[m_board];
}
Exemple #5
0
void Walker::startMove()
{
    int totalPointInGraph = mPointsInPathGraph.size();
    int randSeq = 1 + rand() % (totalPointInGraph - 1);
    
    nextMove(randSeq);
}
Exemple #6
0
Move AbstractGame::findMove(PositionSet markedPositions) const {
  for(Move m = firstMove(); m; m = nextMove(m)) {
    if(*m == markedPositions) {
      return m;
    }
  }
  return NULL;
}
TEST(ValidMoveRightTest, ValidMoveReturnsSameMoveIfItIsValid){
	std::list<Position> allPosns;
	allPosns.push_back(Position(Vector2(0, 0), 50, 50));

	ValidMove validity(Position(Vector2(0, 0), 500, 500), allPosns);
	Vector2 speed(25, 0);
	Position nextMove(Vector2(25, 0), 50, 50);
	Position validMove = validity.getValidMove(Position(Vector2(0, 0), 50, 50), speed);
	
	EXPECT_EQ(validMove, nextMove); 
}
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    boardWidget = new BoardViewer(this);
    ui->scrollArea->setWidget(boardWidget);

    connect(ui->nextMoveButtton,SIGNAL(clicked()),boardWidget,SLOT(nextMove()));
    connect(ui->clearButton,SIGNAL(clicked()),boardWidget,SLOT(clearBoard()));
    connect(ui->randomFillButton,SIGNAL(clicked()),boardWidget,SLOT(randomFill()));
    connect(ui->zoomInButton,SIGNAL(clicked()),boardWidget,SLOT(zoomIn()));
    connect(ui->zoomOutButton,SIGNAL(clicked()),boardWidget,SLOT(zoomOut()));
    connect(ui->sizeDownButton,SIGNAL(clicked()),boardWidget,SLOT(sizeDown()));
    connect(ui->sizeUpButton,SIGNAL(clicked()),boardWidget,SLOT(sizeUp()));
    connect(ui->cycledBorderButton,SIGNAL(toggled(bool)),boardWidget,SLOT(setBorderTypeCycled(bool)));
    connect(ui->deadBorderButton,SIGNAL(toggled(bool)),boardWidget,SLOT(setBorderTypeDead(bool)));
    connect(ui->mobiusBorderButton,SIGNAL(toggled(bool)),boardWidget,SLOT(setBorderTypeMobius(bool)));
    connect(ui->resetButton,SIGNAL(clicked()),boardWidget,SLOT(reset()));
    connect(ui->resetButton,SIGNAL(clicked()),this,SLOT(reset()));



    QSettings settings;
    int borderType=settings.value("/Settings/BorderType",GameBoard::borderCycled).toInt();
    switch (borderType)
    {
    case GameBoard::borderCycled: ui->cycledBorderButton->setChecked(true); break;
    case GameBoard::borderDead:   ui->deadBorderButton->setChecked(true); break;
    case GameBoard::borderMobius: ui->mobiusBorderButton->setChecked(true); break;
    }

    coords = new QLabel(this);
    generationNumber = new QLabel(this);
    generationNumber->setText(" "+tr("Покоління")+": 0");
    coords->setText("(-,-)");
    coords->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
    coords->setMinimumWidth(coordLabelWidth);

    ui->statusBar->addWidget(coords);
    ui->statusBar->addWidget(generationNumber);

    connect(boardWidget,SIGNAL(changeGeneration(int)),this,SLOT(generationChanged(int)));
    connect(boardWidget,SIGNAL(changeCoords(QString,QString)),this,SLOT(coordsChanged(QString,QString)));

    ui->action_about->setShortcut(Qt::Key_F1);
    connect(ui->action_about,SIGNAL(triggered()),this,SLOT(aboutProgram()));
    connect(ui->action_Qt,SIGNAL(triggered()),this,SLOT(aboutQt()));

    ui->action_open->setShortcut(Qt::CTRL + Qt::Key_O);
    ui->action_save->setShortcut(Qt::CTRL + Qt::Key_S);
    connect(ui->action_open,SIGNAL(triggered()),this,SLOT(loadFromFile()));
    connect(ui->action_save,SIGNAL(triggered()),this,SLOT(saveToFile()));
}
Exemple #9
0
Move AbstractGame::findBestMove(MoveResultArray &moveArray, PlayLevel level) {
  moveArray.clear();
  for(Move m = firstMove(); m; m = nextMove(m)) {
    doMove(m);
    const PositionStatus status = getPositionStatus();
    moveArray.add(MoveWithResult(m, MAKE_STATUS(IS_LOOSERSTATUS(status),PLIESTOEND(status)+1)));
    undoMove(m);
  }
  moveArray.sort();
  return moveArray.selectBestMove(level, m_bricksOnBoard);
}
Exemple #10
0
/**
 * \fn MovementList* pathReConstruction(Node* finalNode)
 * \brief Searches through the list, the path.
 * 
 * \param finalNode The destination node.
 * \return The direction an enemy must go.
 */
MovementList* pathReConstruction(Map *map, Node* finalNode) {
	Node* nextNode = finalNode;
	MovementList* list = newMovementList(STAY);
	while(finalNode->previousNode) {
		nextNode = finalNode;
		finalNode = finalNode->previousNode;
		Case* currentCase = getCase(map, finalNode->x, finalNode->y);
		Case* nearCase = getCase(map, nextNode->x, nextNode->y);
		
		list = headMovement(nextMove(*currentCase, *nearCase), list);
	}
	return list;
}
Exemple #11
0
/* Tail starts here */
int main(void) {
    int pos[2], i;
    char board[5][5];
    char line[5];
    scanf("%d", &pos[0]);
    scanf("%d", &pos[1]);
    for(i=0; i<5; i++) {
        scanf("%s", line);
        strncpy(board[i], line, 5);
    }
    nextMove(pos[0], pos[1], board);
    return 0;
}
Exemple #12
0
sf::Vector2f& AStar::GetNextMove()
{

	sf::Vector2f nextMove(m_goal.x, m_goal.y);

	if(!m_path.empty())
	{
		nextMove = m_path[m_path.size()-1];
		m_path.pop_back();
	}

	return nextMove;
}
//! [2]
void xandosdroid::onInvoked(const bb::system::InvokeRequest& request) {
    if (request.action().compare("bb.action.START") == 0) {
        qDebug() << "XandOsDroid : start requested";
        // once the headless is started, communicate back to ui that its ready to play
        connectToServer();
    } else if (request.action().compare("bb.action.STOP") == 0) {
        qDebug() << "XandOsDroid: stop request";
        // terminate headless droid
        terminateDroid();
    } else if (request.action().compare("bb.action.CHOICE") == 0) {
        int choice = QString(request.data()).toInt();
        qDebug() << "XandOsDroid: received user choice: " << choice;
        // mark the user selection in the grid matrix and update the
        // game matrix state
        select(choice, 1);
        // verify there are still moves available
        if (availableChoices().isEmpty()) {
            qDebug() << "XandOsDroid: game over!";
            terminateDroid();
        }
        // Check whether you have any two in a row sequences
        int nextM = nextMove(-2);
        // If no, than block the user based on his possible selections for
        // a consecutive sequence
        if (-1 == nextM) {
            nextM = nextMove(1);
        }
        qDebug() << "XandOsDroid: droid selection: " << nextM;
        // send your next selection to the UI.
        sendSelection(nextM);

    } else {
        qDebug() << "XandOsDroid : unknown service request "
                << request.action();
    }
}
int 
main(int argc, char *argv[])
{
  int n, x, y;

  scanf("%d", &n);
  scanf("%d", &x);
  scanf("%d", &y);
  
  char grid[n][n];
  for(int i = 0; i < n; i++){
    scanf("%s", grid[i]);
  }
  nextMove(n, x, y, grid);
  return 0;
}
Exemple #15
0
/* Tail starts here */
int main(void) {
    
    int x, y;
    int pacman_x, pacman_y;
    int food_x, food_y;
    scanf( "%d %d", &pacman_x, &pacman_y);
    scanf( "%d %d", &food_x, &food_y);
    scanf( "%d %d", &x, &y);
    char grid[x][y];
    
    for( int i=0; i<x; i++) {
        scanf("%s[^\\n]%*c", grid[i]);
    }
    nextMove( x, y, pacman_x, pacman_y, food_x, food_y, grid);
    return 0;
}
Exemple #16
0
/* Tail starts here */
int main(void) {

  int i,n, x, y;
  
  scanf("%d", &n);
  scanf("%d", &x);
  scanf("%d", &y);

  char grid[101][101];
    
  for(i=0; i<n; i++) {
    scanf("%s[^\n]%*c", grid[i]);
  }
  nextMove(n, x, y, grid);
  return 0;
}
int main(void) {

	int n, r, c;

	scanf("%d", &n);
	scanf("%d", &r);
	scanf("%d", &c);

	char grid[101][101];

	for(int i=0; i<n; i++) {
		scanf("%s[^\n]%*c", grid[i]);
	}

	nextMove(n, r, c, grid);
	return 0;
}
Exemple #18
0
int main(void) {

    int i;
    char player;
    char board[3][3];
    char s[3];

    //If player is X, I'm the first player.
    //If player is O, I'm the second player.
    scanf("%c", &player);

    //Read the board now. The board is a 3x3 array filled with X, O or _.
    for(i=0; i<3; i++) {
        scanf("%s[^\n]%*c", board[i]);
    }
    nextMove(player,board);
    return 0;
}
SetPartition AdjBestOneElementMove::Run(const SetPartitionVector& SPV)
{
	SetPartition candidate(FindBestOfK(SPV));
	

	unsigned int n = candidate.GetN();

	// Main loop
	while (true)
	{
		// Find best move
		double S = SPV.SumOfAdjustedRandDistance(candidate);
		double bestDeltaS = 0.0;
		int bestElement = 1, bestBlock = 1;
		
		for (int el = 1; el <= n; ++el)
		{
			for (int block = 1; block <= candidate.NumberOfBlocks(); ++block)
			{
				int blockFrom = candidate.WhichBlock(el);
				if (blockFrom == block)
					continue;

				SetPartition nextMove(candidate);

				nextMove.OneElementMove(el, block);
				double deltaS = SPV.SumOfAdjustedRandDistance(nextMove) - S;
				if (deltaS < bestDeltaS)
				{
					bestDeltaS = deltaS;
					bestElement = el;
					bestBlock = block;
				}
			}
		}

		if (bestDeltaS >= 0.0)
			break;

		candidate.OneElementMove(bestElement, bestBlock);
	}

	return candidate;
}
int main(int argc,char * argv[])
{
	int row=rowCount(argv[1]);
	int col=colCount(argv[1]);
	printf("%d %d\n",row,col);
	int speed;
	FILE * action=fopen(argv[2],"r");
	char * dir=(char*)malloc(sizeof(char)*100);
	char ** arr;
	arr=init(row,col);
	scanVal(argv[1],arr,row,col);
	while(!(feof(action)))
	{
		fscanf(action,"%s",dir);
		if(feof(action)) break;
		speed=nextMove(arr,row,col,dir);
	}
	printVal(arr,row,col);
	return 1;
}
Exemple #21
0
void Walker::onMoveFinished()
{
    auto iter = mPointsInPathGraph.find(mTargetSeq);
    int type = iter->second.type;
    if (type != POINT_TYPE_MOVE)
    {
        nextWork(type);
    }
    else
    {
        nextMove(mTargetSeq);
    }
    /*
    if (false)
    {

        CCCallFunc * fun1 = CCCallFunc::create(this, callfunc_selector(Walker::onWorkFinished));
       
        playAnimation(WalkerActionStatus::WALKER_ACTION_MOVE, 0.1, fun1, 10);
        
    }
    */
}
Exemple #22
0
void GameWidget::setController(GameController *gc)
{
    _gameController = gc;

    QBrush brush(QColor("red"));
    QPen pen(brush, 2);
    QPen pacmanPen(QBrush(QColor("yellow")), 2);
    QPen ghostPen(QBrush(QColor("cyan")), 2);

    // creation de la map
    unsigned int vertexNumber = _gameController->getVertexNumber();
    for(unsigned int i = 0; i < vertexNumber; ++i)
    {
        QGraphicsEllipseItem * ell = new QGraphicsEllipseItem( -GameWidget::RADIUS,
                                                               -GameWidget::RADIUS,
                                                               GameWidget::RADIUS * 2,
                                                               GameWidget::RADIUS * 2 );
        ell->setPen( pen );
        ell->setZValue(1);

        _vertex.push_back( ell );
        _scene->addItem( _vertex.back() );
    }

    positionVertex(_vertex.begin(), _vertex.end());

    linkVertex(_scene, _vertex);

    // creation du pacman et des ghosts
    _pacman = new QGraphicsEllipseItem( -GameWidget::RADIUS + GameWidget::THICK * 2,
                                        -GameWidget::RADIUS + GameWidget::THICK * 2,
                                        GameWidget::RADIUS * 2 - GameWidget::THICK * 4,
                                        GameWidget::RADIUS * 2 - GameWidget::THICK * 4
                                        );
    _pacman->setPen(pacmanPen);
    _scene->addItem(_pacman);
    this->updatePacman();

    std::vector<unsigned int> ghostsPos = _gameController->getGhost();
    unsigned int ghostNumber = ghostsPos.size();
    for( unsigned int i = 0; i < ghostNumber; ++i )
    {
        QGraphicsEllipseItem * ghost = new QGraphicsEllipseItem( -GameWidget::RADIUS + GameWidget::THICK,
                                                                 -GameWidget::RADIUS + GameWidget::THICK,
                                                                 GameWidget::RADIUS * 2 - GameWidget::THICK * 2,
                                                                 GameWidget::RADIUS * 2 - GameWidget::THICK * 2
                                                                 );
        ghost->setPen(ghostPen);
        _scene->addItem(ghost);
        _ghosts.push_back(ghost);
    }
    this->updateGhost();

    QObject::connect(_btnNextMove, SIGNAL(clicked()), this, SLOT(nextMove()));


    _gameController->setPacmanAI(_option.getPacmanAI());
    //_gameController->benchmark(1000);
    //_gameController->reset();

    _view->setFocus();
}
/*
 * avatarMake
 *
 * Function: Initialize each avatar and send move messages during their respective turns
 *
 * Input: @id - current avatar's ID
 *
 */
void *avatarMake (void *id){
  int avatarID = (intptr_t)id;

  // Creating ready message
  AM_Message am_ready;
  memset(&am_ready, 0, sizeof(AM_Message));
  am_ready.type = htonl(AM_AVATAR_READY);
  am_ready.avatar_ready.AvatarId = htonl(avatarID);

  // Creting socket for the avatar
  int sockId;
  if ((sockId = socket(AF_INET, SOCK_STREAM, 0)) < 0){
    fprintf(stderr, "ERROR IN SOCKET 2");
    fprintf(logFile, "ERROR IN SOCKET");
    exit(1);
  }

  // Connect the client to socket                                                             
  if (connect(sockId, (struct sockaddr *) &maze_address, sizeof(maze_address)) < 0) {
    fprintf(stderr, "There was a problem connecting client to the socket 2\n");
    fprintf(logFile, "There was a problem connecting client to the socket\n");    
    exit(1);
  }

  // Sending message to our server
  send(sockId,&am_ready,sizeof(am_ready),0);
  
  // Receiving and checking reply from server
  AM_Message receiveMessage;
  if (recv(sockId,&receiveMessage,sizeof(receiveMessage),0) == 0){
    fprintf(stderr,"The server connection was closed 2\n");
    fprintf(logFile,"The server connection was closed\n");    
    exit(1);
  }
  
  if (ntohl(receiveMessage.type) != AM_AVATAR_TURN){
    fprintf(stderr,"Initialization failed 2");
    fprintf(logFile,"Initialization failed");
    exit(1);
  }
 
  // initialize avatar position
  pthread_mutex_lock(&init_mutex);
  avatarGroup[avatarID]->currpos->x = ntohl(receiveMessage.avatar_turn.Pos[avatarID].x);
  avatarGroup[avatarID]->currpos->y = ntohl(receiveMessage.avatar_turn.Pos[avatarID].y);
  avatarGroup[avatarID]->prevpos->x = avatarGroup[avatarID]->currpos->x;
  avatarGroup[avatarID]->prevpos->y = avatarGroup[avatarID]->currpos->y;
  pthread_mutex_unlock(&init_mutex);

  avFlag++;

  while(avFlag != avatarNum){
    sleep(1);
  }

  int move;
  while(1){
    // enters only on the avatar's specified turn
    if(ntohl(receiveMessage.avatar_turn.TurnId) == avatarID){

      pthread_mutex_lock(&turn_mutex);
      totalMoves++;
      fprintf(logFile,"\nMOVE #%d\n",totalMoves);
      fprintf(logFile,"avatar %d is at position (%d,%d)\n",avatarID,avatarGroup[avatarID]->currpos->x,avatarGroup[avatarID]->currpos->y);
      
      turnID = avatarID;

      setTarget();
      
      // figure out what move to make (FIX NESW)
      move = nextMove(avatarID, avatarGroup[avatarID]->currpos,avatarGroup[avatarID]->prevpos);
      
      if (move == -1){
        fprintf(stderr, "Maze node null\n");
        fprintf(logFile,"Maze node null\n");
        exit(1);
      }
      
      
      // print to file saying what move the avatar is trying to make
      fprintf(logFile,"Avatar %d is trying to move %s \n",avatarID,translateDirection(move));
      // Create move message
      AM_Message moveMessage;
      memset(&moveMessage,0,sizeof(AM_Message));
      moveMessage.type = htonl(AM_AVATAR_MOVE);
      moveMessage.avatar_move.Direction = htonl(move);
      moveMessage.avatar_move.AvatarId = htonl(avatarID);
      
      // Sending move message
      send(sockId,&moveMessage,sizeof(moveMessage),0);

      //receive and check message
      while (ntohl(receiveMessage.avatar_turn.TurnId) == avatarID){
        if (recv(sockId,&receiveMessage,sizeof(receiveMessage),0) == 0){
        fprintf(stderr,"The server connection was closed 3\n");
        fprintf(logFile,"The server connection was closed\n");
        exit(1);
        }

        if( totalMoves == (AM_MAX_MOVES*(difficulty+1)*avatarNum)){
          if(terminate == 0){
            fprintf(stderr,"Exceeded the max number of moves\n");
            fprintf(logFile,"\nEXCEEDED THE MAX NUMBER OF MOVES");
            terminate = 1;
          }
          exit (1);
        }
  
        if(ntohl(receiveMessage.type) == AM_MAZE_SOLVED){
          DrawMaze(height, width, avatarGroup, maze, avatarID, avatarNum, filename);
          if (terminate == 0 ){
            printf("solved");
            fprintf(logFile,"\nMAZE SOLVED!");
            terminate = 1;
          }
          return 0;
        }
        
        if(IS_AM_ERROR(ntohl(receiveMessage.type))){
          fprintf(stderr,"Error from the server 3");
          fprintf(logFile,"Error from the server");
          exit(1);
        }
      }

      if (move != M_NULL_MOVE){
        XYPos *tmp = (XYPos *)malloc(sizeof(XYPos));
        tmp->x = ntohl(receiveMessage.avatar_turn.Pos[avatarID].x);
        tmp->y = ntohl(receiveMessage.avatar_turn.Pos[avatarID].y);
        if (avatarMoved(avatarID, avatarGroup[avatarID]->currpos, tmp, move) == 1){
          // if the avatar moved, update its previous and current positions
          avatarGroup[avatarID]->prevpos->x = avatarGroup[avatarID]->currpos->x;
          avatarGroup[avatarID]->prevpos->y = avatarGroup[avatarID]->currpos->y;
          avatarGroup[avatarID]->currpos->x = tmp->x;
          avatarGroup[avatarID]->currpos->y = tmp->y;
        }
        free(tmp);
      }
     
      // update the maze graphic
      DrawMaze(height, width, avatarGroup, maze, avatarID, avatarNum, filename);
      pthread_mutex_unlock(&turn_mutex);
    }
    // when it's not an avatar's turn, it continues to check server messages
    else{
        //receive and check message
      if (recv(sockId,&receiveMessage,sizeof(receiveMessage),0) == 0){
        if(terminate == 0 ){
          fprintf(stderr,"The server connection was closed 3\n");
          fprintf(logFile,"The server connection was closed\n");
          terminate = 1;
        }
        exit(1);
      }

      if( totalMoves == (AM_MAX_MOVES*(difficulty+1)*avatarNum) ){
              if(terminate == 0){
          fprintf(stderr,"Exceeded the max number of moves\n");
          fprintf(logFile,"\nEXCEEDED MAX NUMBER OF MOVES");
          terminate = 1;
        }
        exit (1);
      }

      if(ntohl(receiveMessage.type) == AM_MAZE_SOLVED){
        DrawMaze(height, width, avatarGroup, maze, avatarID, avatarNum, filename);
        if(terminate == 0){
          printf("solved");
          fprintf(logFile,"\nMAZE SOLVED!");
          terminate = 1;
        }
        return 0;
      }
      
      if(IS_AM_ERROR(ntohl(receiveMessage.type))){
        if(terminate == 0){
          fprintf(stderr,"Error from the server 3");
          fprintf(logFile,"Error from the server");
          terminate = 1;
        }
        exit(1);
      }

    }
  }
  
  return 0;
}
Exemple #24
0
// the main function, transferred in engine. Setting all the graphics stuff as children of Graphics and so on allowed me to make the functions slimmer
int Engine::start(Pattern patt)
{
    //int tmpx = 2, tmpy = 2;
    
    // For second plays
    cleanEnemyFleet();
    cleanLasers();
    
    lastTriggered = EVE_DEFAULT;
    
    
    // For intermediate animations.
    int intervalLaserCounter = 0;
    int turnCounter = 0;
    
    // For managing the laser shooting
    int lasercounter = 0;
    bool readyToFire = true;
    int passTurnTimer = 30;
    
    currentPattern = patt;
    
    // Getting the pointer straight
    protagonist = nullptr;
    
    expiredEnemy0 = false;
    expiredEnemy1 = false;
    
    //Start up SDL and create window
    
    // Here go all the things I need to start up the game. Eventually they'll get into a new nice function.
    // Main loop flag
    bool quit = false;
    
    // Event handler
    SDL_Event e;
    
    // Background color
    SDL_SetRenderDrawColor(graphEngine->getRenderer(), 255, 255, 255, 1);
    
    // Reminder of the last displayed
    Screens gLastDisplayed = MAIN_CAMERA;
    
    // Is there an enemy?
    enemyOnScreen = false;
    
    // First ship
    addProtagonist();
    
    // The address of the enemy ship hit by lasers each turn
    Spaceship* hitTarget = nullptr;
    
    //First drawing
    SDL_RenderClear(graphEngine->getRenderer());
    graphEngine->setView(MAIN_CAMERA);
    gLastDisplayed = MAIN_CAMERA;
    drawFleet(graphEngine);
    SDL_RenderPresent(graphEngine->getRenderer());
    SDL_Delay(300); // TO DECUPLICATE
    
    while( !quit )
    {
        // This is to achieve a nice stable framerate
        Uint32 time = SDL_GetTicks();
        
        //Handle events on queue
        while (SDL_PollEvent (&e) != 0)
        {
            //User requests quit
            if (e.type == SDL_QUIT)
            {
                quit = true;
            }
            
            // User presses a key
            else if (e.type == SDL_KEYDOWN)
            {
                switch (e.key.keysym.sym)
                {
                    case SDLK_x:
                    {
                        protagonist->setAtk(500);
                        break;
                    }
                    case SDLK_n:
                    {
                        protagonist->setAtk(20);
                        break;
                    }
                    case SDLK_ESCAPE:
                    {
                        quit = true;
                        break;
                    }
                    default:
                        break;
                }
            }
            // Things over this brace are only invoked at the press of a button
        }
        // Here I invoke the functions I need each time
        
        // This moves the ship on the position of the mouse.
        // Must start later
        int tX = 0, tY = 0;
        SDL_GetMouseState(&tX, &tY);
        // Ths avoids me going out of screen
        if (tX > SCREEN_WIDTH-40) {
            tX = SCREEN_WIDTH-40;
        }
        if (tX < 2) {
            tX = 2;
        }
        if (tY > SCREEN_HEIGHT-40) {
            tY = SCREEN_HEIGHT-40;
        }
        if (tY < 2) {
            tY = 2;
        }
        
        protagonist->teleport(tX, tY);
        
        // TODO: Regulate this treshold to achieve believable rate of fire
        if (!quit && intervalLaserCounter==3) {
            intervalLaserCounter = 1;
            if (lasercounter == 1) {
                lasercounter --;
                readyToFire = true;
            }
            else {
                lasercounter++;
            }
        }
        
        graphEngine->setView(gLastDisplayed);
        
        // These two are no longer troublesome
        graphEngine->printScore(score);
        graphEngine->printkills(kills);
        printHealth();
        
        if (lastTriggered == GAME_LOST) {
            SDL_Delay(50); // TO DECUPLICATE
            quit = true;
        }
        else if (lastTriggered == MAIN_STAGE_CLEAR && currentPattern == MAIN_STAGE) {
            quit = true;
        }
        else if (lastTriggered == BOSS_STAGE_CLEAR && currentPattern == BOSS_STAGE) {
            quit = true;
        }
        
        if (readyToFire && enemyOnScreen) { // I shall make the count start from a certain turn
            readyToFire = false;
            // Contrarily to popular belief, lasers do NOT cause memory leaks.
            protagonistShootsSingleLaser();
            //areLasersAimed = true;
        }
        
        nextMove(turnCounter, currentPattern, graphEngine);
        
        // Damaging enemies
        bool explosionPlayed = false;
        for (int i = 0; i<static_cast<int>(lasersOnMap.size()); i++) {
            hitTarget = nullptr;
            
            if (lasersOnMap[i]->isMFD()) {
                delete(lasersOnMap[i]);
                lasersOnMap.erase(lasersOnMap.begin()+i);
                if (!explosionPlayed) {
                    Mix_PlayChannel(-1, graphEngine->getBoom(), 0);
                    explosionPlayed = true;
                }
            }
            else if (lasersOnMap[i]->isHittingWall()) {
                delete(lasersOnMap[i]);
                lasersOnMap.erase(lasersOnMap.begin()+i);
            }
            else if (laserIsHittingTarget(i, hitTarget)) {
                if (hitTarget != nullptr){
                    hitTarget->takeDamage(lasersOnMap[i]->getPower());
                    if (!hitTarget->isAlive() && !hitTarget->isAllied()) {
                        kills++;
                        score += 500;
                        explosion tmp = {static_cast<int>(hitTarget->getCenterX()), static_cast<int>(hitTarget->getCenterY()), 10};
                        kabooms.push_back(tmp);
                    }
                    lasersOnMap[i]->explode();
                }
                hitTarget = nullptr;
            }
        }
        // Killing the enemy
        for (int i = 0; i<enemyFleet.size(); i++) {
            if (enemyOnScreen == true && enemyFleet[i]->getHP() <= 0) {
                hitTarget = nullptr;
            }
        }
        bool everyoneDead = true;
        for (int i = 0; i<enemyFleet.size(); i++) {
            if (enemyFleet[i]->isAlive()) {
                everyoneDead = false;
            }
        }
        if (everyoneDead) {
            enemyOnScreen = false;
        }
        //Adding points
        score += (SDL_GetTicks() - time);
        
        // Cleaning the lasers
        for (int i = 0; i<lasersOnMap.size(); i++) {
            //if (!areLasersAimed) {
            lasersOnMap[i]->travel();
            //}
            // This is all in case I ever want to aim the lasers again
            /*
            else {
                if (lasersOnMap[i]->isSBA() && enemyOnScreen) {
                    int x = 0, y = 0;
                    coordsOfNearestEnemy(x, y, i, false);
                    
                    int cosfact = x - lasersOnMap[i]->getCentergX();
                    int sinfact = y - lasersOnMap[i]->getCentergY();
                    double targAngle;
                    if (cosfact != 0) {
                        targAngle = atan2(sinfact, cosfact);
                    }
                    else {
                        if (sinfact > 0) {
                            targAngle = pi/2;
                        }
                        else {
                            targAngle = -pi/2;
                        }
                    }
                    lasersOnMap[i]->setAngle(-targAngle);
                    lasersOnMap[i]->travel();
                }
                else {
                    lasersOnMap[i]->travel();
                }
            }
            */
        }
        if (enemyFleet.size() == 0) {
            enemyOnScreen = false;
        }
        if (protagonist->getHP() <= 0) {
            setLastEvent(GAME_LOST);
        }
        if (turnCounter > 2000 && !enemyOnScreen && currentPattern == MAIN_STAGE) {
            if (passTurnTimer == 0) {
                cleanEnemyFleet();
                cleanLasers();
                setLastEvent(MAIN_STAGE_CLEAR);
            }
            else {
                passTurnTimer--;
            }
        }
        if (turnCounter > 20 && !enemyOnScreen && currentPattern == BOSS_STAGE) {
            if (passTurnTimer == 0) {
                cleanEnemyFleet();
                cleanLasers();
                setLastEvent(BOSS_STAGE_CLEAR);
            }
            else {
                passTurnTimer--;
            }
        }
        for (int i = 0; i<kabooms.size(); i++) {
            if (kabooms[i].timer == 0) {
                kabooms.erase(kabooms.begin()+i);
            }
        }
        for (int i = 0; i<kabooms.size(); i++) {
            OtherSprites fireball = rand() >= RAND_MAX/2 ? SHIP_EXPLODE_1 : SHIP_EXPLODE_2;
            double zF = (10-kabooms[i].timer);
            zF /= 10;
            graphEngine->printOtherOnScreen(fireball, kabooms[i].x, kabooms[i].y, 0, zF, 80, 80);
            kabooms[i].timer -= 1;
        }
        
        drawFleet(graphEngine);
        drawEnemyFleet(graphEngine);
        
        // Must render here else explosion will not be seen
        for (int i = 0; i<lasersOnMap.size(); i++) {
            lasersOnMap[i]->drawOnScreen(graphEngine);
        }
        
        /*
         SDL_SetRenderDrawColor(graphEngine->getRenderer(), 255, 0, 0, 0);
         SDL_RenderFillRect(graphEngine->getRenderer(), &fillRect1);
         SDL_RenderFillRect(graphEngine->getRenderer(), &fillRect2);
         SDL_RenderFillRect(graphEngine->getRenderer(), &fillRect3);
         SDL_RenderFillRect(graphEngine->getRenderer(), &fillRect4);
         */
        
        intervalLaserCounter++;
        turnCounter++;
        SDL_RenderPresent(graphEngine->getRenderer());
        
        if((1000/FPS)>(SDL_GetTicks()-time))
        {
            SDL_Delay((1000/FPS)-(SDL_GetTicks()-time)); //SDL_Delay pauses the execution.
        }
    }
    // Here ends the main loop
    //Free resources and close SDL
    return 0;
}