void WorkerSlave::handleToken() {
    int colorReceived;
    MPI_Recv(&colorReceived, 1, MPI_INT, previousprocesor, MSG_TOKEN, MPI_COMM_WORLD, &status);
    int c;
    if (colorReceived == BLACK || color == BLACK) {
        c = BLACK;
    } else {
        c = WHITE;
    }
    sendToken(c);
}
void WorkerMaster::workparalel() {    
    double t1, t2;
    MPI_Barrier(MPI_COMM_WORLD); /* cekam na spusteni vsech procesu */
    t1 = MPI_Wtime(); /* pocatecni cas */

    while (running) {
        tokenCounter++;
        counter++;
        if (counter % MODULO == 0) {
            counter = 1;
            if (staciklist.empty()) {
                color = WHITE;
                sendRequestForWork(nextProcesor);
            } else {
                color = BLACK;
                // cout << myRank << ": ";
                work();
            }
            handleCommunication();
        }
        if (tokenCounter % TOKEN_MODULO == 0) {
            tokenCounter = 1;
            if (color == WHITE) {
                if (!waitingForToken) {
                    waitingForToken = true;
                    sendToken(color);
                }
            }
        }
    }
    //waiting for solutions
    getBestSolutionFromProcessors();
    
    result->printResult();
    delete result;
    
    smallMistakeResult->printResult();
    delete smallMistakeResult;
    
    MPI_Barrier(MPI_COMM_WORLD); /* cekam na dokonceni vypoctu */
    t2 = MPI_Wtime(); /* koncovy cas */
    printf ("Spotrebovany cas je %f.\n",t2-t1);
}
void Solver::solve(vector<Move>& _solution) {
    lowerBound = initBoard->getLowerBound(targetTower);
    bestSolutionDepth = maxDepth;

    if (myRank != MASTER_RANK) {
        //cekam az mi prijde prace
        //prvni rozdeleni se udela automaticky bez zadani
        //cekam dokud message neprijde melo by prijit prvni deleni prace
        //momentalne to prvni spocte takzee prijde pesek
        MPI_Status s;
        MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &s);

        processMessages();

    } else {
        // Hotovo, koncim.
        if (initBoard->isTowerComplete(targetTower)) {
            broadcast(MESSAGE_FINISHED);
            return;
        }
        Move firstMove(0, 0, 0);
        SpaceItem* firstSpaceItem = new SpaceItem(*initBoard, firstMove);
        space.push_back(firstSpaceItem);
        expandTop();
        actualDepth = 1;
        firstWorkDistribution = true;
        space.erase(space.begin());
    }
    int counter = 0;

    while (!finished) {
        if (!space.empty()) {
            proccessTop(_solution, actualDepth);
        } else {

            requestData();
            sendToken();
        }

        if (counter == 150) {//natipovat idealni honotu
            if ((myRank == MASTER_RANK) && firstWorkDistribution) {
                firstDistribution();
                counter = 0;
            } else {
                counter = 0;
                processMessages();

                if (finished) {
                    char buffer[BUFFER_SIZE];
                    int position = 0;

                    serializeSolution(buffer, position, _solution);

                    char result[BUFFER_SIZE];

                    MPI_Op op;
                    MPI_Op_create((MPI_User_function*) compare, 0, &op);
                  //  cout<<_solution.size()<<endl;
                    MPI_Reduce(&buffer, &result, BUFFER_SIZE, MPI_PACKED, op, 0, MPI_COMM_WORLD);
                    int workRequestsRes;
                    MPI_Reduce (&workRequestsInt, &workRequestsRes, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
                    int failedWorkRequestsRes;
                    MPI_Reduce (&failedWorkRequests, &failedWorkRequestsRes, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
                    if (myRank == MASTER_RANK) {
                        vector<Move> solution;
                        int position = 0;
                        deserializeSolution(result, position, solution);

                        cout << "MASTER - ZACATEK RESENI" << endl;
                        for (vector<Move>::const_iterator it = solution.begin(); it < solution.end(); ++it) {
                            cout << *it << endl;
                        }
                        cout << "Solution depth: " << solution.size() << endl;
                        cout<< "Work Requests: "<<workRequestsRes<<endl;
                        cout<<"Denied Work Requests: "<<failedWorkRequestsRes<<endl;
                        
                        cout << "MASTER - KONEC RESENI" << endl;
                    }
                }
            }
        }
        counter++;
    }

    //   cout << "PushCount process " << myRank << ": " << pushCount << endl;
    //   cout << "Solution: " << _solution.size() << " - process " << myRank << endl;
    //   cout << "mam jeste: " << space.size() << " stavu" << endl;
}