<commit_before>/**************************************************************************
 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//-------------------------------------------------------------------------
//     AOD Pid class to store additional pid information
//     Author: Annalisa Mastroserio
//-------------------------------------------------------------------------

#include "AliAODPid.h"
#include "AliESDtrack.h"
#include "AliLog.h"
#include "AliPID.h"
#include "AliTPCdEdxInfo.h"

ClassImp(AliAODPid)

//______________________________________________________________________________
AliAODPid::AliAODPid():
    fITSsignal(0),
    fTPCsignal(0),
    fTPCsignalN(0),
    fTPCmomentum(0),
    fTRDnSlices(0),
    fTRDntls(0),
    fTRDslices(0x0),
    fTOFesdsignal(0),
    fHMPIDsignal(0),
    fTPCdEdxInfo(0)
{
  // default constructor
    for(Int_t i=0; i<kSPECIES; i++) fIntTime[i]   = 0;
    for(Int_t i=0; i<5; i++) fHMPIDprobs[i] = 0.;
    for(Int_t i=0; i<3; i++) fEMCALPosition[i]    = 0.;
    for(Int_t i=0; i<5; i++) fTOFpidResolution[i] = 0.;
    for(Int_t i=0; i<6; i++) {
      fTRDmomentum[i]      = 0.;
      fTRDncls[i]          = 0;
    }
    for(Int_t i=0; i<3; i++) fEMCALMomentum[i]    = 0.;
    for(Int_t i=0; i<4; i++) fITSdEdxSamples[i]   = 0.;
}

//______________________________________________________________________________
AliAODPid::~AliAODPid()
{
  delete [] fTRDslices;
  fTRDslices = 0;
  delete fTPCdEdxInfo;
  // destructor
}

//______________________________________________________________________________
AliAODPid::AliAODPid(const AliAODPid& pid) :
  TObject(pid),
  fITSsignal(pid.fITSsignal),
  fTPCsignal(pid.fTPCsignal),
  fTPCsignalN(pid.fTPCsignalN),
  fTPCmomentum(pid.fTPCmomentum),
  fTRDnSlices(pid.fTRDnSlices),
  fTRDntls(pid.fTRDntls),
  fTRDslices(0x0),
  fTOFesdsignal(pid.fTOFesdsignal),
  fHMPIDsignal(pid.fHMPIDsignal),
  fTPCdEdxInfo(new AliTPCdEdxInfo(*pid.fTPCdEdxInfo))
{
  // Copy constructor
  SetTRDsignal(fTRDnSlices, pid.fTRDslices);
    for(Int_t i=0; i<kSPECIES; i++) fIntTime[i]=pid.fIntTime[i];
    for(Int_t i=0; i<5; i++) fHMPIDprobs[i] = pid.fHMPIDprobs[i];
    for(Int_t i=0; i<3; i++) {
      fEMCALPosition[i]=pid.fEMCALPosition[i];
      fEMCALMomentum[i]=pid.fEMCALMomentum[i];
    }
    for(Int_t i=0; i<6; i++){
      fTRDmomentum[i]=pid.fTRDmomentum[i];
      fTRDncls[i] = 0;
    }

    for(Int_t i=0; i<5; i++) fTOFpidResolution[i]=pid.fTOFpidResolution[i];

    for(Int_t i=0; i<4; i++) fITSdEdxSamples[i]=pid.fITSdEdxSamples[i];
}

//______________________________________________________________________________
AliAODPid& AliAODPid::operator=(const AliAODPid& pid)
{
  // Assignment operator
  if(this!=&pid) {
    // copy stuff
    TObject::operator=(pid);

    fITSsignal   = pid.fITSsignal;
    for (Int_t i = 0; i < 4; i++) fITSdEdxSamples[i]=pid.fITSdEdxSamples[i];
    fTPCsignal   = pid.fTPCsignal;
    fTPCsignalN  = pid.fTPCsignalN;
    fTPCmomentum = pid.fTPCmomentum;

    if(fTRDnSlices != pid.fTRDnSlices) {
      // only delete if number changed or is 0
      delete [] fTRDslices;
      fTRDslices = 0;
      fTRDnSlices = pid.fTRDnSlices;
      if(pid.fTRDnSlices > 0) fTRDslices = new Double32_t[fTRDnSlices];
    }

    if (fTRDslices && pid.fTRDslices)
      memcpy(fTRDslices, pid.fTRDslices, fTRDnSlices*sizeof(Double32_t));

    fTRDntls = pid.fTRDntls;
    for(Int_t i = 0; i < 6; i++){
	fTRDmomentum[i] = pid.fTRDmomentum[i];
	fTRDncls[i]     = pid.fTRDncls[i];
    }

    fTOFesdsignal=pid.fTOFesdsignal;
    for (Int_t i = 0; i < 5; i++) fTOFpidResolution[i]=pid.fTOFpidResolution[i];
    for (Int_t i = 0; i < 5; i++) fIntTime[i]=pid.fIntTime[i];

    fHMPIDsignal=pid.fHMPIDsignal;

    for(Int_t i = 0; i < 5; i++) fHMPIDprobs[i] = pid.fHMPIDprobs[i];

    for(Int_t i = 0; i < 3; i++) {
	fEMCALPosition[i]=pid.fEMCALPosition[i];
	fEMCALMomentum[i]=pid.fEMCALMomentum[i];
    }
  }

  return *this;
}
//_______________________________________________________________________________
void AliAODPid::GetIntegratedTimes(Double_t timeint[kSPECIES]) const
{
 // Returns the array with integrated times for each particle hypothesis
for(Int_t i=0; i<kSPECIES; i++) timeint[i]=fIntTime[i];
}
//_______________________________________________________________________________
void AliAODPid::SetIntegratedTimes(Double_t timeint[kSPECIES])
{
 // Returns the array with integrated times for each particle hypothesis
for(Int_t i=0; i<kSPECIES; i++) fIntTime[i]=timeint[i];
}
//_______________________________________________________________________________
void AliAODPid::GetEMCALPosition(Double_t emcalpos[3]) const
{
 // Returns the array with extrapolated track position at the EMCAL surface
  for(Int_t i=0; i<3; i++) emcalpos[i]=fEMCALPosition[i];
}
//_______________________________________________________________________________
void AliAODPid::SetEMCALPosition(Double_t emcpos[3])
{
 // Sets the array with extrapolated track position at the EMCAL surface
  for(Int_t i=0; i<3; i++) fEMCALPosition[i]=emcpos[i];
}
//_______________________________________________________________________________
void AliAODPid::GetEMCALMomentum(Double_t emcalmom[3]) const
{
 // Returns the array with extrapolated track momentum at the EMCAL surface
  for(Int_t i=0; i<3; i++) emcalmom[i]=fEMCALMomentum[i];
}
//_______________________________________________________________________________
void AliAODPid::SetEMCALMomentum(Double_t emcmom[3])
{
 // Sets the array with extrapolated track momentum at the EMCAL surface
  for(Int_t i=0; i<3; i++) fEMCALMomentum[i]=emcmom[i];
}
//______________________________________________________________________________
void AliAODPid::SetTOFpidResolution(Double_t tofPIDres[5])
{
  for (Int_t i=0; i<5; i++) fTOFpidResolution[i]=tofPIDres[i];

}
//______________________________________________________________________________
void AliAODPid::GetTOFpidResolution(Double_t tofRes[5]) const
{
  for (Int_t i=0; i<5; i++) tofRes[i]=fTOFpidResolution[i];
}

//______________________________________________________________________________
void AliAODPid::SetHMPIDprobs(Double_t hmpPid[5])
{
  //
  // Set the HMPID PID probablities that are read from ESD
  //
  for(Int_t i = 0; i < 5; i++ ) fHMPIDprobs[i] =  hmpPid[i];
}
//______________________________________________________________________________
void AliAODPid::GetHMPIDprobs(Double_t *p) const
{
  //
  // Set the HMPID PID probablities that are read from ESD
  //
  for(Int_t i = 0; i < AliPID::kSPECIES; i++ ) p[i] =  fHMPIDprobs[i];
}
//______________________________________________________________________________
void AliAODPid::SetITSdEdxSamples(const Double_t s[4])
{
  //
  // Set the 4 values of dE/dx from individual ITS layers that are read from ESD
  //
  for (Int_t i=0; i<4; i++) fITSdEdxSamples[i]=s[i];
}
//______________________________________________________________________________
void AliAODPid::GetITSdEdxSamples(Double_t s[4]) const
{
  //
  // Get the 4 values of dE/dx from individual ITS layers that are read from ESD
  //
  for (Int_t i=0; i<4; i++) s[i]=fITSdEdxSamples[i];
}
//______________________________________________________________________________
void AliAODPid::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo)
{
  //
  // Set TPC dEdx info
  //
  if (dEdxInfo==0x0){
    delete fTPCdEdxInfo;
    fTPCdEdxInfo=0x0;
    return;
  }
  if (!fTPCdEdxInfo) fTPCdEdxInfo=new AliTPCdEdxInfo;
  (*fTPCdEdxInfo)=(*dEdxInfo);
}

<commit_msg>Bug fix (Jens)<commit_after>/**************************************************************************
 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//-------------------------------------------------------------------------
//     AOD Pid class to store additional pid information
//     Author: Annalisa Mastroserio
//-------------------------------------------------------------------------

#include "AliAODPid.h"
#include "AliESDtrack.h"
#include "AliLog.h"
#include "AliPID.h"
#include "AliTPCdEdxInfo.h"

ClassImp(AliAODPid)

//______________________________________________________________________________
AliAODPid::AliAODPid():
    fITSsignal(0),
    fTPCsignal(0),
    fTPCsignalN(0),
    fTPCmomentum(0),
    fTRDnSlices(0),
    fTRDntls(0),
    fTRDslices(0x0),
    fTOFesdsignal(0),
    fHMPIDsignal(0),
    fTPCdEdxInfo(0)
{
  // default constructor
    for(Int_t i=0; i<kSPECIES; i++) fIntTime[i]   = 0;
    for(Int_t i=0; i<5; i++) fHMPIDprobs[i] = 0.;
    for(Int_t i=0; i<3; i++) fEMCALPosition[i]    = 0.;
    for(Int_t i=0; i<5; i++) fTOFpidResolution[i] = 0.;
    for(Int_t i=0; i<6; i++) {
      fTRDmomentum[i]      = 0.;
      fTRDncls[i]          = 0;
    }
    for(Int_t i=0; i<3; i++) fEMCALMomentum[i]    = 0.;
    for(Int_t i=0; i<4; i++) fITSdEdxSamples[i]   = 0.;
}

//______________________________________________________________________________
AliAODPid::~AliAODPid()
{
  delete [] fTRDslices;
  fTRDslices = 0;
  delete fTPCdEdxInfo;
  // destructor
}

//______________________________________________________________________________
AliAODPid::AliAODPid(const AliAODPid& pid) :
  TObject(pid),
  fITSsignal(pid.fITSsignal),
  fTPCsignal(pid.fTPCsignal),
  fTPCsignalN(pid.fTPCsignalN),
  fTPCmomentum(pid.fTPCmomentum),
  fTRDnSlices(pid.fTRDnSlices),
  fTRDntls(pid.fTRDntls),
  fTRDslices(0x0),
  fTOFesdsignal(pid.fTOFesdsignal),
  fHMPIDsignal(pid.fHMPIDsignal),
  fTPCdEdxInfo(0x0)
{
  // Copy constructor
  SetTRDsignal(fTRDnSlices, pid.fTRDslices);
    for(Int_t i=0; i<kSPECIES; i++) fIntTime[i]=pid.fIntTime[i];
    for(Int_t i=0; i<5; i++) fHMPIDprobs[i] = pid.fHMPIDprobs[i];
    for(Int_t i=0; i<3; i++) {
      fEMCALPosition[i]=pid.fEMCALPosition[i];
      fEMCALMomentum[i]=pid.fEMCALMomentum[i];
    }
    for(Int_t i=0; i<6; i++){
      fTRDmomentum[i]=pid.fTRDmomentum[i];
      fTRDncls[i] = 0;
    }

    for(Int_t i=0; i<5; i++) fTOFpidResolution[i]=pid.fTOFpidResolution[i];

    for(Int_t i=0; i<4; i++) fITSdEdxSamples[i]=pid.fITSdEdxSamples[i];

    if (pid.fTPCdEdxInfo) fTPCdEdxInfo=new AliTPCdEdxInfo(*pid.fTPCdEdxInfo);
}

//______________________________________________________________________________
AliAODPid& AliAODPid::operator=(const AliAODPid& pid)
{
  // Assignment operator
  if(this!=&pid) {
    // copy stuff
    TObject::operator=(pid);

    fITSsignal   = pid.fITSsignal;
    for (Int_t i = 0; i < 4; i++) fITSdEdxSamples[i]=pid.fITSdEdxSamples[i];
    fTPCsignal   = pid.fTPCsignal;
    fTPCsignalN  = pid.fTPCsignalN;
    fTPCmomentum = pid.fTPCmomentum;

    if(fTRDnSlices != pid.fTRDnSlices) {
      // only delete if number changed or is 0
      delete [] fTRDslices;
      fTRDslices = 0;
      fTRDnSlices = pid.fTRDnSlices;
      if(pid.fTRDnSlices > 0) fTRDslices = new Double32_t[fTRDnSlices];
    }

    if (fTRDslices && pid.fTRDslices)
      memcpy(fTRDslices, pid.fTRDslices, fTRDnSlices*sizeof(Double32_t));

    fTRDntls = pid.fTRDntls;
    for(Int_t i = 0; i < 6; i++){
	fTRDmomentum[i] = pid.fTRDmomentum[i];
	fTRDncls[i]     = pid.fTRDncls[i];
    }

    fTOFesdsignal=pid.fTOFesdsignal;
    for (Int_t i = 0; i < 5; i++) fTOFpidResolution[i]=pid.fTOFpidResolution[i];
    for (Int_t i = 0; i < 5; i++) fIntTime[i]=pid.fIntTime[i];

    fHMPIDsignal=pid.fHMPIDsignal;

    for(Int_t i = 0; i < 5; i++) fHMPIDprobs[i] = pid.fHMPIDprobs[i];

    for(Int_t i = 0; i < 3; i++) {
	fEMCALPosition[i]=pid.fEMCALPosition[i];
	fEMCALMomentum[i]=pid.fEMCALMomentum[i];
    }
    SetTPCdEdxInfo(pid.fTPCdEdxInfo);
  }

  return *this;
}
//_______________________________________________________________________________
void AliAODPid::GetIntegratedTimes(Double_t timeint[kSPECIES]) const
{
 // Returns the array with integrated times for each particle hypothesis
for(Int_t i=0; i<kSPECIES; i++) timeint[i]=fIntTime[i];
}
//_______________________________________________________________________________
void AliAODPid::SetIntegratedTimes(Double_t timeint[kSPECIES])
{
 // Returns the array with integrated times for each particle hypothesis
for(Int_t i=0; i<kSPECIES; i++) fIntTime[i]=timeint[i];
}
//_______________________________________________________________________________
void AliAODPid::GetEMCALPosition(Double_t emcalpos[3]) const
{
 // Returns the array with extrapolated track position at the EMCAL surface
  for(Int_t i=0; i<3; i++) emcalpos[i]=fEMCALPosition[i];
}
//_______________________________________________________________________________
void AliAODPid::SetEMCALPosition(Double_t emcpos[3])
{
 // Sets the array with extrapolated track position at the EMCAL surface
  for(Int_t i=0; i<3; i++) fEMCALPosition[i]=emcpos[i];
}
//_______________________________________________________________________________
void AliAODPid::GetEMCALMomentum(Double_t emcalmom[3]) const
{
 // Returns the array with extrapolated track momentum at the EMCAL surface
  for(Int_t i=0; i<3; i++) emcalmom[i]=fEMCALMomentum[i];
}
//_______________________________________________________________________________
void AliAODPid::SetEMCALMomentum(Double_t emcmom[3])
{
 // Sets the array with extrapolated track momentum at the EMCAL surface
  for(Int_t i=0; i<3; i++) fEMCALMomentum[i]=emcmom[i];
}
//______________________________________________________________________________
void AliAODPid::SetTOFpidResolution(Double_t tofPIDres[5])
{
  for (Int_t i=0; i<5; i++) fTOFpidResolution[i]=tofPIDres[i];

}
//______________________________________________________________________________
void AliAODPid::GetTOFpidResolution(Double_t tofRes[5]) const
{
  for (Int_t i=0; i<5; i++) tofRes[i]=fTOFpidResolution[i];
}

//______________________________________________________________________________
void AliAODPid::SetHMPIDprobs(Double_t hmpPid[5])
{
  //
  // Set the HMPID PID probablities that are read from ESD
  //
  for(Int_t i = 0; i < 5; i++ ) fHMPIDprobs[i] =  hmpPid[i];
}
//______________________________________________________________________________
void AliAODPid::GetHMPIDprobs(Double_t *p) const
{
  //
  // Set the HMPID PID probablities that are read from ESD
  //
  for(Int_t i = 0; i < AliPID::kSPECIES; i++ ) p[i] =  fHMPIDprobs[i];
}
//______________________________________________________________________________
void AliAODPid::SetITSdEdxSamples(const Double_t s[4])
{
  //
  // Set the 4 values of dE/dx from individual ITS layers that are read from ESD
  //
  for (Int_t i=0; i<4; i++) fITSdEdxSamples[i]=s[i];
}
//______________________________________________________________________________
void AliAODPid::GetITSdEdxSamples(Double_t s[4]) const
{
  //
  // Get the 4 values of dE/dx from individual ITS layers that are read from ESD
  //
  for (Int_t i=0; i<4; i++) s[i]=fITSdEdxSamples[i];
}
//______________________________________________________________________________
void AliAODPid::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo)
{
  //
  // Set TPC dEdx info
  //
  if (dEdxInfo==0x0){
    delete fTPCdEdxInfo;
    fTPCdEdxInfo=0x0;
    return;
  }
  if (!fTPCdEdxInfo) fTPCdEdxInfo=new AliTPCdEdxInfo;
  (*fTPCdEdxInfo)=(*dEdxInfo);
}

<|endoftext|>


<commit_before>/**************************************************************
COSC 501
Elliott Plack
14 NOV 2013                            Due date: 30 NOV 2013

Problem:
	Write a program that plays the game of HANGMAN(guessing a
	mystery word).  Read a word to be guessed from a file into
	successive elements of the array WORD. The player must
	guess the letters belonging to WORD. A single guessing
	session should be terminated when either all letters have
	been guessed correctly (player wins) or a specified number
	of incorrect guesses have been made (computer wins). A run
	must consist of at least two sessions: one player wins and
	one computer wins. The player decides whether or not to
	start a new session.

***************************************************************/

#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
#include <time.h> // for random
using namespace std;

ifstream inFile;     // define ifstream to inFile command

void readString();
void initialize(unsigned long); // function to initalize everything
void guess();
void hangmanDraw(int, int, string);

// global variables
string word; // word to be read from file (the solution)
string solution; // solution (guessed by user)
unsigned long wordLength; // length of word

// functions

int main() // reads in the file and sets the functions in motion
{
	readString(); // reads the file and stores variables
	initialize(wordLength); // sends length of word to initialize function
	guess(); // game logic

	return 0;
}

void readString()
{
	int random20 = 0; // random number
	string dictionary[20]; // 20 words to load from file

	inFile.open("Words4Hangman.txt"); // open input file

	while (inFile.good())
	{
		for (int i = 0; i < 20; i++)
		{
			inFile >> dictionary[i]; // load file and fill dict
		}
	}

	inFile.close(); // close the file

	srand((int)time(NULL)); // initialize random seed
	random20 = (rand() % 20); // set random to 20 +-

	word = dictionary[rand() % 20]; // set word = to a random letter in the dictionary
	//cout << word << endl; // cheater! (testing)
	wordLength = word.size(); // size (length) of the string
}

void initialize(unsigned long wordLength)
{
	solution.assign(wordLength, '*'); // fills up the solution string (an array) with as many *s as the word length
}

void guess()
{
	char guessLetter = ' '; // letter to guess
	int winning = 0, goodGuess = 0; // variable to check if the game is won or the guess is good
	int guessesCounter = 7; // hangman countdown

	hangmanDraw(guessesCounter, winning, solution); // show blank

	while ((guessesCounter > 0) && (winning == 0))
	{

		cout << "Guess a letter: ";
		cin >> guessLetter;
		guessLetter = toupper(guessLetter); // make guess uppercase

		for (unsigned long i = 0; i < wordLength; i++) // loop through word looking for guess
		{
			if (guessLetter == word[i])
			{
				//cout << "char " << (i + 1) /* +1 because first is 0*/ << " is " << guessLetter << endl; // outputs that guess was correct
				solution[i] = guessLetter; // set the i char in solution to guessLetter
				goodGuess = 1; // sets the flag goodGuess = 1 for the logic below
			}
		}

		if (solution == word) // thus victory
		{
			winning = 1; // you won
			hangmanDraw(guessesCounter, winning, solution);
		}
		else if (goodGuess == 1)
		{
			goodGuess = 0; // clear flag for next run
			hangmanDraw(guessesCounter, winning, solution);
		}
		else
		{
			guessesCounter--; // decrement guess
			hangmanDraw(guessesCounter, winning, solution);
		}
	}
}

void hangmanDraw(int guessNumber, int winningResult, string solutionDisplay)
{
	// set up strings for game
	string hD01 = "    /\\  /\\__ _ _ __   __ _ _ __ ___   __ _ _ __  \n"; // have to escape out backslash
	string hD02 = "   / /_/ / _` | '_ \\ / _` | '_ ` _ \\ / _` | '_ \\ \n"; // have to escape out backslash
	string hD03 = "  / __  / (_| | | | | (_| | | | | | | (_| | | | |\n";
	string hD04 = "  \\/ /_/ \\__,_|_| |_|\\__, |_| |_| |_|\\__,_|_| |_|\n"; // have to escape out backslash
	string hD05 = "                     |___/                       \n";
	string hD06 = "                            by Elliott Plack     \n";
	string hD07 = "                                                 \n";
	string hD08 = "      _______                                    \n";
	string hD09 = "     |/      |          ______________________   \n";
	string hD10 = "     |                 |                      |  \n";
	string hD11 = "     |                 | Your Progress        |  \n";
	string hD12 = "     |                 |                      |  \n";
	string hD13 = "     |                 |                      |  \n";
	string hD14 = "     |                 |                      |  \n";
	string hD15 = "  ___|___              |______________________|  \n";

	// set up body parts
	string head = "(_)";
	string neck = "|";
	string leftArm = "\\";
	string rightArm = "/";
	string torso = "|";
	string leftLeg = "/";
	string rightLeg = "\\";
	const char space = ' ';
	string youWon = "YOU WON !!";
	string youLose = "YOU DIED !";

	//system("CLS"); // clear the input screen

	if (guessNumber <= 7 && winningResult == 0)
	{
		switch (guessNumber)
		{
		case 7:
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 6:
			hD10 = hD10.replace(12, 3, head);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 5:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 1, leftArm);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 4:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 2, leftArm + neck);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 3:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 3, leftArm + neck + rightArm);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 2:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 3, leftArm + neck + rightArm);
			hD12 = hD12.replace(13, 1, torso);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 1:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 3, leftArm + neck + rightArm);
			hD12 = hD12.replace(13, 1, torso);
			hD13 = hD13.replace(12, 2, leftLeg + space);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 0:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 3, leftArm + neck + rightArm);
			hD12 = hD12.replace(13, 1, torso);
			hD13 = hD13.replace(12, 3, leftLeg + space + rightLeg);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			hD14 = hD14.replace(31, 10, youLose);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		default:
			cout << "\aError!";
			break;
		}
	}
	else if (winningResult == 1)
	{
		hD13 = hD13.replace(25, wordLength, solutionDisplay);
		hD14 = hD14.replace(31, 10, youWon);
		cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
			<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
	}
}<commit_msg>added while loop in main, fixes #1<commit_after>/**************************************************************
COSC 501
Elliott Plack
14 NOV 2013                            Due date: 30 NOV 2013

Problem:
	Write a program that plays the game of HANGMAN(guessing a
	mystery word).  Read a word to be guessed from a file into
	successive elements of the array WORD. The player must
	guess the letters belonging to WORD. A single guessing
	session should be terminated when either all letters have
	been guessed correctly (player wins) or a specified number
	of incorrect guesses have been made (computer wins). A run
	must consist of at least two sessions: one player wins and
	one computer wins. The player decides whether or not to
	start a new session.

***************************************************************/

#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
#include <time.h> // for random
using namespace std;

ifstream inFile;     // define ifstream to inFile command

void readString();
void initialize(unsigned long); // function to initalize everything
void guess();
void hangmanDraw(int, int, string);

// global variables
string word; // word to be read from file (the solution)
string solution; // solution (guessed by user)
unsigned long wordLength; // length of word

// functions

int main() // reads in the file and sets the functions in motion
{
	char repeat = 'Y'; // test if user wants to repeat
	while (repeat == 'Y' || repeat == 'y')
	{
		readString(); // reads the file and stores variables
		initialize(wordLength); // sends length of word to initialize function
		guess(); // game logic

		cout << "Do you want to play again? Y/N: ";
		cin >> repeat;
	}
	return 0;
}

void readString()
{
	int random20 = 0; // random number
	string dictionary[20]; // 20 words to load from file

	inFile.open("Words4Hangman.txt"); // open input file

	while (inFile.good())
	{
		for (int i = 0; i < 20; i++)
		{
			inFile >> dictionary[i]; // load file and fill dict
		}
	}

	inFile.close(); // close the file

	srand((int)time(NULL)); // initialize random seed
	random20 = (rand() % 20); // set random to 20 +-

	word = dictionary[rand() % 20]; // set word = to a random letter in the dictionary
	//cout << word << endl; // cheater! (testing)
	wordLength = word.size(); // size (length) of the string
}

void initialize(unsigned long wordLength)
{
	solution.assign(wordLength, '*'); // fills up the solution string (an array) with as many *s as the word length
}

void guess()
{
	char guessLetter = ' '; // letter to guess
	int winning = 0, goodGuess = 0; // variable to check if the game is won or the guess is good
	int guessesCounter = 7; // hangman countdown

	hangmanDraw(guessesCounter, winning, solution); // show blank

	while ((guessesCounter > 0) && (winning == 0))
	{

		cout << "Guess a letter: ";
		cin >> guessLetter;
		guessLetter = toupper(guessLetter); // make guess uppercase

		for (unsigned long i = 0; i < wordLength; i++) // loop through word looking for guess
		{
			if (guessLetter == word[i])
			{
				//cout << "char " << (i + 1) /* +1 because first is 0*/ << " is " << guessLetter << endl; // outputs that guess was correct
				solution[i] = guessLetter; // set the i char in solution to guessLetter
				goodGuess = 1; // sets the flag goodGuess = 1 for the logic below
			}
		}

		if (solution == word) // thus victory
		{
			winning = 1; // you won
			hangmanDraw(guessesCounter, winning, solution);
		}
		else if (goodGuess == 1)
		{
			goodGuess = 0; // clear flag for next run
			hangmanDraw(guessesCounter, winning, solution);
		}
		else
		{
			guessesCounter--; // decrement guess
			hangmanDraw(guessesCounter, winning, solution);
		}
	}
}

void hangmanDraw(int guessNumber, int winningResult, string solutionDisplay)
{
	// set up strings for game
	string hD01 = "    /\\  /\\__ _ _ __   __ _ _ __ ___   __ _ _ __  \n"; // have to escape out backslash
	string hD02 = "   / /_/ / _` | '_ \\ / _` | '_ ` _ \\ / _` | '_ \\ \n"; // have to escape out backslash
	string hD03 = "  / __  / (_| | | | | (_| | | | | | | (_| | | | |\n";
	string hD04 = "  \\/ /_/ \\__,_|_| |_|\\__, |_| |_| |_|\\__,_|_| |_|\n"; // have to escape out backslash
	string hD05 = "                     |___/                       \n";
	string hD06 = "                            by Elliott Plack     \n";
	string hD07 = "                                                 \n";
	string hD08 = "      _______                                    \n";
	string hD09 = "     |/      |          ______________________   \n";
	string hD10 = "     |                 |                      |  \n";
	string hD11 = "     |                 | Your Progress        |  \n";
	string hD12 = "     |                 |                      |  \n";
	string hD13 = "     |                 |                      |  \n";
	string hD14 = "     |                 |                      |  \n";
	string hD15 = "  ___|___              |______________________|  \n";

	// set up body parts
	string head = "(_)";
	string neck = "|";
	string leftArm = "\\";
	string rightArm = "/";
	string torso = "|";
	string leftLeg = "/";
	string rightLeg = "\\";
	const char space = ' ';
	string youWon = "YOU WON !!";
	string youLose = "YOU DIED !";

	//system("CLS"); // clear the input screen

	if (guessNumber <= 7 && winningResult == 0)
	{
		switch (guessNumber)
		{
		case 7:
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 6:
			hD10 = hD10.replace(12, 3, head);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 5:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 1, leftArm);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 4:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 2, leftArm + neck);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 3:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 3, leftArm + neck + rightArm);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 2:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 3, leftArm + neck + rightArm);
			hD12 = hD12.replace(13, 1, torso);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 1:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 3, leftArm + neck + rightArm);
			hD12 = hD12.replace(13, 1, torso);
			hD13 = hD13.replace(12, 2, leftLeg + space);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		case 0:
			hD10 = hD10.replace(12, 3, head);
			hD11 = hD11.replace(12, 3, leftArm + neck + rightArm);
			hD12 = hD12.replace(13, 1, torso);
			hD13 = hD13.replace(12, 3, leftLeg + space + rightLeg);
			hD13 = hD13.replace(25, wordLength, solutionDisplay);
			hD14 = hD14.replace(31, 10, youLose);
			cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
				<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
			break;
		default:
			cout << "\aError!";
			break;
		}
	}
	else if (winningResult == 1)
	{
		hD13 = hD13.replace(25, wordLength, solutionDisplay);
		hD14 = hD14.replace(31, 10, youWon);
		cout << hD01 << hD02 << hD03 << hD04 << hD05 << hD06 << hD07
			<< hD08 << hD09 << hD10 << hD11 << hD12 << hD13 << hD14 << hD15;
	}
}<|endoftext|>


<commit_before>#define _WINSOCKAPI_

#include <stdio.h>
#include <string>
#include <settings_class.h>
#include <iostream>
#include <windows.h>
#include <qpop_server.h>
#include <gdiplus.h>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <img_processing.h>
#include <screen_capturer.h>
#include <ancillary_functions.h>
#include <shared_access.h>
#define RUNNING_DIR "./"

Qpop_Server main_server;

void ModifyThread();
void MonitorCondition(Qpop_Server* server, struct Scaling_Info* input, tagSIZE* img_dimensions, std::string exe_name);

int main(){
	std::cout << "Starting Main Program";
	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
   	ULONG_PTR gdiplusToken;
   	Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
	// Load the presets from the folder. If not available, create presets.
	FILE* default_settings; // Lists all contained profiles. Should be altered when a profile is added
	FILE* default_profile; // Contains the original LoL profile for testing
	_profile_name = "League of Legends";
	boost::property_tree::ptree data;
	boost::property_tree::ptree profiles;
	boost::property_tree::ptree tmp_ptree;
	std::deque<float> threshold_holder;
	_close_qpop = 0;
	struct Scaling_Info info;
	if(!(default_settings = fopen("default.xml", "r"))){
		std::cout << "Settings file not found\n";
		// add comments and spacing
		default_settings = fopen("default.xml", "w");
		default_profile = fopen("lol.xml", "w");
		fwrite("<total></total><path><profile_path></profile_path></path>", sizeof(char), 68, default_settings); // Write base XML class for profile paths
		fwrite("<db><profile><config_name></config_name><default_res_x></default_res_x><default_res_y></default_res_y><process></process><base_dir></base_dir><images><x></x><y></y><img_name></img_name><threshold></threshold></images></profile></db>\0", sizeof(char), 232, default_profile); // Write base XML for a "profile"
		fclose(default_settings); // add error check for this seciton
		fclose(default_profile);
		try{
			boost::property_tree::xml_parser::read_xml("lol.xml", data);
			// Add check for lol directory
			if(!boost::filesystem::is_directory("./lol/")){
				//TODO: create assets in lol, such as pictures
				boost::filesystem::create_directory("lol");
			}
			std::cout << "Inputting Default Values\n";
			//Input defaults into lol.xml These values were found in a previous project
			data.put("db.profile.config_name", "League of Legends");
			data.put("db.profile.base_dir", "./lol/");
			data.put("db.profile.images.img_name", "play.png"); //ad img_name for variety of images of join buttons
			data.put("db.profile.process", "LolClient.exe");
			//offset
			data.put("db.profile.default_res_x", 1280);
			data.put("db.profile.default_res_y", 720);
			data.put("db.profile.images.x", 561);
			data.put("db.profile.images.y", 14);
			data.put("db.profile.images.threshold", 60);
			//second image
			tmp_ptree.put("img_name", "aram.png");
			//offset
			tmp_ptree.put("x", 497);
			tmp_ptree.put("y", 435);
			tmp_ptree.put("threshold", 79);
			data.add_child("db.profile.images", tmp_ptree);
			//Set up default value - league of legends in this case
			boost::property_tree::xml_parser::write_xml("lol.xml", data);
			// Move to proper directory
			boost::filesystem::rename("lol.xml", "./lol/lol.xml");
			//install();
		}catch(const std::exception &e){
			std::cerr << e.what();
			exit(1);
		}

		//Close data ptrees?
		try{
			//Insert where to load directory
			boost::property_tree::xml_parser::read_xml("default.xml", profiles);
			profiles.put("path.profile_path", std::string(RUNNING_DIR) + "lol/lol.xml");
			profiles.put("total", 1);
			boost::property_tree::xml_parser::write_xml("default.xml", profiles);
		}catch( const std::exception &e){
			std:: cerr << e.what();
			exit(1);
		}
	}
	else{
		fclose(default_settings);
		boost::property_tree::xml_parser::read_xml("default.xml", profiles);
		std::cout << "Settings File found\n";
	}
	boost::thread thread1(ModifyThread);
	// Load Profiles
	int num_profiles = profiles.get<int>("total");
	Settings_Profile* profile_list = new Settings_Profile[num_profiles];
	boost::property_tree::ptree::const_iterator iter = profiles.begin();
	boost::property_tree::ptree::const_iterator img_iter;
	boost::property_tree::ptree temp_tree;
	iter++;
	std::string file_name;
	std::cout << "number of profiles to load: " << num_profiles << std::endl;
	for(int x = 0; x < num_profiles; x++){
		file_name = iter->second.get_child("profile_path").data();
		std::cout << "Loading profile from " << file_name;
		boost::property_tree::xml_parser::read_xml(file_name, data);
		std::cout << "\nLoading: " << data.get<std::string>("db.profile.config_name") << "\n";
		profile_list[x].setConfigName(data.get<std::string>("db.profile.config_name"));
		try{
			img_iter = data.get_child("db.profile").begin();
			//Iterate until images field is reached
			while(std::string(img_iter->first.data()).compare("images") != 0) img_iter++;
			std::string field = img_iter->first.data();
			//img_iter->first.data();
			//std::string field = img_iter->second.get_child("images").data();
			std::string float_holder;
			while(!field.compare("images")){
				profile_list[0].addImgName(img_iter->second.get_child("img_name").data());
				std::cout << "Test Image Name: " << img_iter->second.get_child("img_name").data();
				float_holder = img_iter->second.get_child("x").data();
				profile_list[0].addX(std::stof(float_holder, NULL));
				float_holder = img_iter->second.get_child("y").data();
				profile_list[0].addY(std::stof(float_holder, NULL));
				threshold_holder.push_back(std::stof(img_iter->second.get_child("threshold").data(), NULL));
				img_iter++;
				field = img_iter->first.data();
			}
		}catch(std::exception e){
			std::cerr << "Error occured: " << e.what();
		}
		//profile_list[x].setX(data.get<float>("db.profile.x"));
		//profile_list[x].setY(data.get<float>("db.profile.y"));
		profile_list[x].setBaseDir(data.get<std::string>("db.profile.base_dir"));
		profile_list[x].setProcessName(data.get<std::string>("db.profile.process"));
		profile_list[x].setDefaultRes(data.get<int>("db.profile.default_res_x"), data.get<int>("db.profile.default_res_y"));
		iter++;
		std::cout << "Loading finished\n";
	}
	std::cout << "Length of images: " << profile_list[0].getImgCount();

	//GUI set current profile placeholder - use global identifier
	Settings_Profile cur_prof = profile_list[0];
	for(int x = 0; x < cur_prof.getImgCount(); x++){
		std::cout << "\nLoading Image: " << cur_prof.getBaseDir() << cur_prof.getImgName(x) << "\n";
		if(!(boost::filesystem::exists(cur_prof.getBaseDir() + cur_prof.getImgName(x)))){
			std::cerr << "\n\tImage file " + cur_prof.getBaseDir() << cur_prof.getImgName(x) << " doesn't exist\n";
		exit(1);
		}
	}

	info.pic_data_array = (struct Pic_Slice*) calloc(sizeof(Pic_Slice), cur_prof.getImgCount());
	for(int x = 0; x < cur_prof.getImgCount(); x++){
		info.pic_data_array[x].bmp = GetHBITMAPFromImageFile(cur_prof.getBaseDir() + cur_prof.getImgName(x));
		info.pic_data_array[x].x = cur_prof.getX(x);
		info.pic_data_array[x].y = cur_prof.getY(x);;
	}
	//**************************Set correct base resolution - it's hardcoded here**************************
	//*****************************************************************************************************
	info.x_scaler = cur_prof.getDResX();
	info.y_scaler = cur_prof.getDresY();
	//*****************************************************************************************************

	std::cout <<"X Scaler: " << info.x_scaler << "Y Scaler: " << info.y_scaler << std::endl;

	float cur_diff = 0;
	float difference = 0;
	tagSIZE* img_dimensions = (tagSIZE*) calloc(sizeof(tagSIZE), cur_prof.getImgCount());
	Gdiplus::Bitmap* tmp = NULL;
	std::string exe_name = cur_prof.getProcessName();
	// Pointer so it can bet deleted before GDUIplusShutdown is called. Otherwise crashing occurs
	for(int x = 0; x < cur_prof.getImgCount(); x++){
		tmp = new Gdiplus::Bitmap(info.pic_data_array[x].bmp, NULL);
		img_dimensions[x].cx = tmp->GetWidth();
		img_dimensions[x].cy = tmp->GetHeight();
	}
	delete tmp;
	info.num_images = cur_prof.getImgCount();
	std::cout << "\nAll Images loaded and dimensions set\n";
	std::cout << "\nWaiting for Match...\n";

	struct result_data rdt;

	main_server.set_port(8000);
	main_server.start_server();
	//_monitor_pause.lock();
	boost::thread monitor_thread(MonitorCondition, &main_server, &info, img_dimensions, exe_name);
	// put click into seperate thread for immediate results
	while(_close_qpop == 0){
		_close_qpop_lock.lock();
		if(_close_qpop == 1){
			_close_qpop_lock.unlock();
			thread1.join();
			// changed to break return 0;
			break;
		}
		_close_qpop_lock.unlock();
		rdt = Screen_Capturer::takeSnapshot(exe_name, Screen_Capturer::compHBITMAP_SEL, (void*) &info);
		std::cout << "comparison finished: \n";
		if(rdt.difference != NULL){
			for(int x = 0; x < cur_prof.getImgCount(); x++){
				printf("Pic %d: diff: %f threshold %f\n", x, rdt.difference[x], threshold_holder.at(x));
				if(threshold_holder.at(x) >0){
					if(rdt.difference[x] < threshold_holder.at(x) && rdt.difference[x] >= 0){
						std::cout << "Threshold limit reached, activating at " << (info.pic_data_array[x].x + img_dimensions[x].cx) * info.scaling_ratio - (img_dimensions[x].cx * info.scaling_ratio / 2) << "x" << (info.pic_data_array[x].y + img_dimensions[x].cy) * info.scaling_ratio - (img_dimensions[x].cy * info.scaling_ratio / 2) << std::endl;
						_img_number_lock.lock();
						_img_number = x;
						_img_number_lock.unlock();
						//_monitor_pause.unlock();
						condition.notify_one();
						main_server.send("popped");
					}
					else{
						main_server.send("queued");
						main_server.setCondition(false);
					}
				}
				if(threshold_holder.at(x) < 0){
					if(rdt.difference[x] > threshold_holder.at(x)*-1 && rdt.difference[x] >= 0){
						std::cout << "Threshold limit reached, activating at " << (info.pic_data_array[x].x + img_dimensions[x].cx) * info.scaling_ratio - (img_dimensions[x].cx * info.scaling_ratio / 2) << "x" << (info.pic_data_array[x].y + img_dimensions[x].cy) * info.scaling_ratio - (img_dimensions[x].cy * info.scaling_ratio / 2) << std::endl;
						_img_number_lock.lock();
						_img_number = x;
						_img_number_lock.unlock();
						//_monitor_pause.unlock();
						condition.notify_one();
						main_server.send("popped");
					}
					else{
						main_server.send("queued");
						main_server.setCondition(false);
					}
				}			}
			delete rdt.difference;
		}
		Sleep(800);
		while(_paused) Sleep(1000);

	}
	thread1.join();
	delete info.pic_data_array;
	delete img_dimensions;
	threshold_holder.clear();
	Gdiplus::GdiplusShutdown(gdiplusToken);
	return 0;
}

void MonitorCondition(Qpop_Server *s, struct Scaling_Info* info, tagSIZE* img_dimensions, std::string exe_name){
	int x = 0;
	while(_close_qpop == 0){
		boost::mutex::scoped_lock lock(_monitor_pause);
		_img_number_lock.lock();
		x = _img_number;
		_img_number_lock.unlock();
		condition.wait(lock);
		if(main_server.conditionSatisfied()){
			ExhaustiveClick((info->pic_data_array[x].x + img_dimensions[x].cx) * info->scaling_ratio - (img_dimensions[x].cx * info->scaling_ratio / 2), (info->pic_data_array[x].y + img_dimensions[x].cy) * info->scaling_ratio - (img_dimensions[x].cy * info->scaling_ratio / 2), exe_name);
			main_server.setCondition(false);
		}
	}
}

/**
 * Run in seperate thread to handle changes from the gui. A pipe is created that is read from and put into the decider
 * the decier tells the thread to pause, run, or quit which it then modifies, for safety with a mutex, so that these
 * rules are applied to the main thread as well.
 */
void ModifyThread(){
	char decider = '0';
	char buffer_read = '3';
	DWORD bytes_read = 0;
	int result = 0;

  HANDLE pipe;
  pipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\deciderpipe"), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT, 1, 8, 8, NMPWAIT_USE_DEFAULT_WAIT, NULL);
  if(pipe == INVALID_HANDLE_VALUE){
  	std::cerr << "\nInvalid Handle Created " << GetLastError() << "\n";
  }
  while(pipe != INVALID_HANDLE_VALUE){
    break;
  }

	if(pipe == INVALID_HANDLE_VALUE){
		std::cerr << "ERROR";
	}
	else std::cout << "SUCESS";

	while(decider != '1'){
		Sleep(200);
		try{
			result = ReadFile(pipe, &buffer_read, 1, &bytes_read, NULL);
		}
		catch(...){
			std::cerr << "Error Occured result: " << result << "Error Code: " << GetLastError() << "\n";
		}
		if(GetLastError() == 109 || result == 0){
			CloseHandle(pipe);
			 pipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\deciderpipe"), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT, 1, 8, 8, NMPWAIT_USE_DEFAULT_WAIT, NULL);
		}
		if(bytes_read > 0) decider = buffer_read;
		if(decider == '1'){
			_close_qpop_lock.lock();
			_close_qpop = decider;
			_close_qpop_lock.unlock();
		}
		if(decider == '2'){
			_paused = 1;
		}
		else _paused = 0;
	}
	CloseHandle(pipe);
	return;
}<commit_msg>removed ptree file loading. moved file loading to profile constructor<commit_after>#define _WINSOCKAPI_

#include <stdio.h>
#include <string>
#include <settings_class.h>
#include <iostream>
#include <windows.h>
#include <qpop_server.h>
#include <gdiplus.h>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <img_processing.h>
#include <screen_capturer.h>
#include <ancillary_functions.h>
#include <shared_access.h>
#define RUNNING_DIR "./"

Qpop_Server main_server;

void ModifyThread();
void MonitorCondition(Qpop_Server* server, struct Scaling_Info* input, tagSIZE* img_dimensions, std::string exe_name);

int main(){
	std::cout << "Starting Main Program" << std::endl;
	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
   	ULONG_PTR gdiplusToken;
   	Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
	Scaling_Info info;
	struct result_data rdt;

   	// Create settings profile for league of legends
   	Settings_Profile cur_prof("lol.txt");

   	// Create scaling info struct. Keeps default  x and y for when window is resized. The resize it then applied
   	// To the location of the buttons

	info.x_scaler = (float) cur_prof.getDResX();
	info.y_scaler = (float) cur_prof.getDresY();

	float cur_diff = 0;
	float difference = 0;
	tagSIZE* img_dimensions = (tagSIZE*) calloc(sizeof(tagSIZE), cur_prof.getImgCount());
	Gdiplus::Bitmap* tmp = NULL;
	std::string exe_name = cur_prof.getProcessName();
	// Pointer so it can be deleted before GDUIplusShutdown is called. Otherwise crashing occurs
	for(int x = 0; x < cur_prof.getImgCount(); x++){
		tmp = new Gdiplus::Bitmap(info.pic_data_array[x].bmp, NULL);
		img_dimensions[x].cx = tmp->GetWidth();
		img_dimensions[x].cy = tmp->GetHeight();
	}
	delete tmp;
	info.num_images = cur_prof.getImgCount();
	std::cout << "\nAll Images loaded and dimensions set\n";
	std::cout << "\nWaiting for Match...\n";

	main_server.set_port(8000);
	main_server.start_server();
	boost::thread monitor_thread(MonitorCondition, &main_server, &info, img_dimensions, exe_name);
	while(_close_qpop == 0){
		rdt = Screen_Capturer::takeSnapshot(exe_name, Screen_Capturer::compHBITMAP_SEL, (void*) &info);
		std::cout << "comparison finished: \n";
		if(rdt.difference != NULL){
			for(int x = 0; x < cur_prof.getImgCount(); x++){
				printf("Pic %d: diff: %f threshold %f\n", x, rdt.difference[x], cur_prof.getThresholdAt(x));
				if(cur_prof.getThresholdAt(x) >0){
					if(rdt.difference[x] < cur_prof.getThresholdAt(x) && rdt.difference[x] >= 0){
						std::cout << "Threshold limit reached, activating at " << (info.pic_data_array[x].x + img_dimensions[x].cx) * info.scaling_ratio - (img_dimensions[x].cx * info.scaling_ratio / 2) << "x" << (info.pic_data_array[x].y + img_dimensions[x].cy) * info.scaling_ratio - (img_dimensions[x].cy * info.scaling_ratio / 2) << std::endl;
						_img_number_lock.lock();
						_img_number = x;
						_img_number_lock.unlock();
						//_monitor_pause.unlock();
						condition.notify_one();
						main_server.send("popped");
					}
					else{
						main_server.send("queued");
						main_server.setCondition(false);
					}
				}
				if(cur_prof.getThresholdAt(x) < 0){
					if(rdt.difference[x] > cur_prof.getThresholdAt(x)*-1 && rdt.difference[x] >= 0){
						std::cout << "Threshold limit reached, activating at " << (info.pic_data_array[x].x + img_dimensions[x].cx) * info.scaling_ratio - (img_dimensions[x].cx * info.scaling_ratio / 2) << "x" << (info.pic_data_array[x].y + img_dimensions[x].cy) * info.scaling_ratio - (img_dimensions[x].cy * info.scaling_ratio / 2) << std::endl;
						_img_number_lock.lock();
						_img_number = x;
						_img_number_lock.unlock();
						//_monitor_pause.unlock();
						condition.notify_one();
						main_server.send("popped");
					}
					else{
						main_server.send("queued");
						main_server.setCondition(false);
					}
				}			}
			delete rdt.difference;
		}
		Sleep(800);
		while(_paused) Sleep(1000);

	}
	delete info.pic_data_array;
	delete img_dimensions;
	Gdiplus::GdiplusShutdown(gdiplusToken);
	return 0;
}

void MonitorCondition(Qpop_Server *s, struct Scaling_Info* info, tagSIZE* img_dimensions, std::string exe_name){
	int x = 0;
	while(_close_qpop == 0){
		boost::mutex::scoped_lock lock(_monitor_pause);
		_img_number_lock.lock();
		x = _img_number;
		_img_number_lock.unlock();
		condition.wait(lock);
		if(main_server.conditionSatisfied()){
			ExhaustiveClick((info->pic_data_array[x].x + img_dimensions[x].cx) * info->scaling_ratio - (img_dimensions[x].cx * info->scaling_ratio / 2), (info->pic_data_array[x].y + img_dimensions[x].cy) * info->scaling_ratio - (img_dimensions[x].cy * info->scaling_ratio / 2), exe_name);
			main_server.setCondition(false);
		}
	}
}

/**
 * Run in seperate thread to handle changes from the gui. A pipe is created that is read from and put into the decider
 * the decier tells the thread to pause, run, or quit which it then modifies, for safety with a mutex, so that these
 * rules are applied to the main thread as well.
 */
void ModifyThread(){
	char decider = '0';
	char buffer_read = '3';
	DWORD bytes_read = 0;
	int result = 0;

  HANDLE pipe;
  pipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\deciderpipe"), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT, 1, 8, 8, NMPWAIT_USE_DEFAULT_WAIT, NULL);
  if(pipe == INVALID_HANDLE_VALUE){
  	std::cerr << "\nInvalid Handle Created " << GetLastError() << "\n";
  }
  while(pipe != INVALID_HANDLE_VALUE){
    break;
  }

	if(pipe == INVALID_HANDLE_VALUE){
		std::cerr << "ERROR";
	}
	else std::cout << "SUCESS";

	while(decider != '1'){
		Sleep(200);
		try{
			result = ReadFile(pipe, &buffer_read, 1, &bytes_read, NULL);
		}
		catch(...){
			std::cerr << "Error Occured result: " << result << "Error Code: " << GetLastError() << "\n";
		}
		if(GetLastError() == 109 || result == 0){
			CloseHandle(pipe);
			 pipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\deciderpipe"), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT, 1, 8, 8, NMPWAIT_USE_DEFAULT_WAIT, NULL);
		}
		if(bytes_read > 0) decider = buffer_read;
		if(decider == '1'){
			_close_qpop_lock.lock();
			_close_qpop = decider;
			_close_qpop_lock.unlock();
		}
		if(decider == '2'){
			_paused = 1;
		}
		else _paused = 0;
	}
	CloseHandle(pipe);
	return;
}<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX600 グループ・ペリフェラル
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2016, 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ペリフェラル種別
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	enum class peripheral : uint16_t {

		MTU0,	///< マルチファンクションタイマパルスユニット０
		MTU1,	///< マルチファンクションタイマパルスユニット１
		MTU2,	///< マルチファンクションタイマパルスユニット２
		MTU3,	///< マルチファンクションタイマパルスユニット３
		MTU4,	///< マルチファンクションタイマパルスユニット４
		MTU5,	///< マルチファンクションタイマパルスユニット５
		MTU6,	///< マルチファンクションタイマパルスユニット６
		MTU7,	///< マルチファンクションタイマパルスユニット７

		TMR0,	///< 8 ビットタイマ０
		TMR1,	///< 8 ビットタイマ１
		TMR2,	///< 8 ビットタイマ２
		TMR3,	///< 8 ビットタイマ３

		CMT0,	///< コンペアマッチタイマ（CMT）
		CMT1,	///< コンペアマッチタイマ（CMT）
		CMT2,	///< コンペアマッチタイマ（CMT）
		CMT3,	///< コンペアマッチタイマ（CMT）

		TPU0,	///< 16 ビットタイマパルスユニット０
		TPU1,	///< 16 ビットタイマパルスユニット１
		TPU2,	///< 16 ビットタイマパルスユニット２
		TPU3,	///< 16 ビットタイマパルスユニット３
		TPU4,	///< 16 ビットタイマパルスユニット４
		TPU5,	///< 16 ビットタイマパルスユニット５

		DTC,		///< データトランスファコントローラ

		ETHERC0,	///< Ethernet 0 (PHY RMII)
		ETHERC1,	///< Ethernet 1 (PHY RMII)
		PTPETHERC,	///< PTP Ethernet

		ETHERCA,	///< Ethernet 0 (PHY RMII)カスタムポート接続

		EDMAC0,		///< Ethernet DMA 0
		EDMAC1,		///< Ethernet DMA 1
		PTPEDMAC,	///< PTP Ethernet DMA

		SCI0,		///< シリアルコミュニケーションインタフェース (P20:TXD0, P21:RXD0)
		SCI1,		///< シリアルコミュニケーションインタフェース (PF0:TXD1, PF2:RXD1)
		SCI2,		///< シリアルコミュニケーションインタフェース (P13:TXD2, P12:RXD2)
		SCI3,		///< シリアルコミュニケーションインタフェース (P23:TXD3, P25:RXD3)
		SCI4,		///< シリアルコミュニケーションインタフェース (PB1:TXD4, PB0:RXD4)
		SCI5,		///< シリアルコミュニケーションインタフェース (PA4:TXD5, PA2:RXD5)
		SCI6,		///< シリアルコミュニケーションインタフェース (P00:TXD6, P01:RXD6)
		SCI7,		///< シリアルコミュニケーションインタフェース (P90:TXD7, P92:RXD7)

		SCIF8,		///< FIFO 内臓シリアルコミュニケーションインターフェース
		SCIF9,		///< FIFO 内臓シリアルコミュニケーションインターフェース
		SCIF10,		///< FIFO 内臓シリアルコミュニケーションインターフェース
		SCIF11,		///< FIFO 内臓シリアルコミュニケーションインターフェース

		SCI12,		///< シリアルコミュニケーションインタフェース

		RIIC0,		///< I 2 C バスインタフェース（RIICa）
		RIIC2,		///< I 2 C バスインタフェース（RIICa）

		RSPI,		///< シリアルペリフェラルインタフェース（RSPIa）
#ifdef SIG_RX71M
		RSPI2,		///< シリアルペリフェラルインタフェース（RSPIb）
#endif
		SSI0,		///< シリアルサウンドインタフェース（SSI）
		SSI1,		///< シリアルサウンドインタフェース（SSI）

		SRC,		///< サンプリングレートコンバータ（SRC）

		SDHI,		///< SD ホストインタフェース（SDHI）

		S12AD,		///< 12 ビット A/D コンバータ（S12ADC）
		S12AD1,		///< 12 ビット A/D コンバータ（S12ADC）

		R12DA,		///< 12 ビット D/A コンバータ（R12DA）

		ECCRAM,		///< ECC RAM (32K)
		STBRAM,		///< Standby RAM (8K)

		// 仮の仕様
		IRQ0,
		IRQ1,
		IRQ2,
		IRQ3,
		IRQ4,
		IRQ5,
		IRQ6,
		IRQ7,
	};
}
<commit_msg>update: GLCDC<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX600 グループ・ペリフェラル
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2016, 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ペリフェラル種別
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	enum class peripheral : uint16_t {

		MTU0,	///< マルチファンクションタイマパルスユニット０
		MTU1,	///< マルチファンクションタイマパルスユニット１
		MTU2,	///< マルチファンクションタイマパルスユニット２
		MTU3,	///< マルチファンクションタイマパルスユニット３
		MTU4,	///< マルチファンクションタイマパルスユニット４
		MTU5,	///< マルチファンクションタイマパルスユニット５
		MTU6,	///< マルチファンクションタイマパルスユニット６
		MTU7,	///< マルチファンクションタイマパルスユニット７

		TMR0,	///< 8 ビットタイマ０
		TMR1,	///< 8 ビットタイマ１
		TMR2,	///< 8 ビットタイマ２
		TMR3,	///< 8 ビットタイマ３

		CMT0,	///< コンペアマッチタイマ（CMT）
		CMT1,	///< コンペアマッチタイマ（CMT）
		CMT2,	///< コンペアマッチタイマ（CMT）
		CMT3,	///< コンペアマッチタイマ（CMT）

		TPU0,	///< 16 ビットタイマパルスユニット０
		TPU1,	///< 16 ビットタイマパルスユニット１
		TPU2,	///< 16 ビットタイマパルスユニット２
		TPU3,	///< 16 ビットタイマパルスユニット３
		TPU4,	///< 16 ビットタイマパルスユニット４
		TPU5,	///< 16 ビットタイマパルスユニット５

		DTC,		///< データトランスファコントローラ

		ETHERC0,	///< Ethernet 0 (PHY RMII)
		ETHERC1,	///< Ethernet 1 (PHY RMII)
		PTPETHERC,	///< PTP Ethernet

		ETHERCA,	///< Ethernet 0 (PHY RMII)カスタムポート接続

		EDMAC0,		///< Ethernet DMA 0
		EDMAC1,		///< Ethernet DMA 1
		PTPEDMAC,	///< PTP Ethernet DMA

		SCI0,		///< シリアルコミュニケーションインタフェース (P20:TXD0, P21:RXD0)
		SCI1,		///< シリアルコミュニケーションインタフェース (PF0:TXD1, PF2:RXD1)
		SCI2,		///< シリアルコミュニケーションインタフェース (P13:TXD2, P12:RXD2)
		SCI3,		///< シリアルコミュニケーションインタフェース (P23:TXD3, P25:RXD3)
		SCI4,		///< シリアルコミュニケーションインタフェース (PB1:TXD4, PB0:RXD4)
		SCI5,		///< シリアルコミュニケーションインタフェース (PA4:TXD5, PA2:RXD5)
		SCI6,		///< シリアルコミュニケーションインタフェース (P00:TXD6, P01:RXD6)
		SCI7,		///< シリアルコミュニケーションインタフェース (P90:TXD7, P92:RXD7)

		SCIF8,		///< FIFO 内臓シリアルコミュニケーションインターフェース
		SCIF9,		///< FIFO 内臓シリアルコミュニケーションインターフェース
		SCIF10,		///< FIFO 内臓シリアルコミュニケーションインターフェース
		SCIF11,		///< FIFO 内臓シリアルコミュニケーションインターフェース

		SCI12,		///< シリアルコミュニケーションインタフェース

		RIIC0,		///< I 2 C バスインタフェース（RIICa）
		RIIC2,		///< I 2 C バスインタフェース（RIICa）

		RSPI,		///< シリアルペリフェラルインタフェース（RSPIa）
#ifdef SIG_RX71M
		RSPI2,		///< シリアルペリフェラルインタフェース（RSPIb）
#endif
		SSI0,		///< シリアルサウンドインタフェース（SSI）
		SSI1,		///< シリアルサウンドインタフェース（SSI）

		SRC,		///< サンプリングレートコンバータ（SRC）

		SDHI,		///< SD ホストインタフェース（SDHI）

		S12AD,		///< 12 ビット A/D コンバータ（S12ADC）
		S12AD1,		///< 12 ビット A/D コンバータ（S12ADC）

		R12DA,		///< 12 ビット D/A コンバータ（R12DA）

		ECCRAM,		///< ECC RAM (32K)
		STBRAM,		///< Standby RAM (8K)

		// 仮の仕様
		IRQ0,
		IRQ1,
		IRQ2,
		IRQ3,
		IRQ4,
		IRQ5,
		IRQ6,
		IRQ7,

		GLCDC,		///< グラフィック LCD コントローラ (GLCDC)
	};
}
<|endoftext|>


<commit_before>#include "RainbowAnimation.h"
#include <stdlib.h>
#include <Arduino.h>

uint32_t Wheel(Adafruit_NeoPixel* strip, byte WheelPos) {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85) {
        return strip->Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    if(WheelPos < 170) {
        WheelPos -= 85;
        return strip->Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    WheelPos -= 170;
    return strip->Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void rainbow(Adafruit_NeoPixel* strip, uint8_t wait) {
    uint16_t i, j;
    for(j = 0; j < 256; j++) {
        for(i = 0; i < strip->numPixels(); i++) {
            strip->setPixelColor(i, Wheel(strip, (i + j) & 255));
        }
        strip->show();
        delay(wait);
    }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(Adafruit_NeoPixel* strip, uint8_t wait) {
    uint16_t i, j;
    for(j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
        for(i=0; i< strip->numPixels(); i++) {
            strip->setPixelColor(i, Wheel(strip, ((i * 256 / strip->numPixels()) + j) & 255));
        }
        strip->show();
        delay(wait);
    }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(Adafruit_NeoPixel* strip, uint8_t wait) {
    for (int j = 0; j < 256; j++) {     // cycle all 256 colors in the wheel
        for (int q = 0; q < 3; q++) {
            for (uint16_t i = 0; i < strip->numPixels(); i = i + 3) {
                strip->setPixelColor(i + q, Wheel(strip, (i + j) % 255));    //turn every third pixel on
            }
            strip->show();

            delay(wait);

            for (uint16_t i = 0; i < strip->numPixels(); i = i + 3) {
                strip->setPixelColor(i + q, 0);        //turn every third pixel off
            }
        }
    }
}

void RainbowAnimation::drawFrame() {
    Adafruit_NeoPixel* strip = this->getStrip();
    rainbow(strip, 20);
    rainbowCycle(strip, 20);
    theaterChaseRainbow(strip, 50);

};
<commit_msg>Fix code formatting<commit_after>#include "RainbowAnimation.h"
#include <stdlib.h>
#include <Arduino.h>

uint32_t Wheel(Adafruit_NeoPixel* strip, byte WheelPos) {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85) {
        return strip->Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    if(WheelPos < 170) {
        WheelPos -= 85;
        return strip->Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    WheelPos -= 170;
    return strip->Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void rainbow(Adafruit_NeoPixel* strip, uint8_t wait) {
    uint16_t i, j;
    for(j = 0; j < 256; j++) {
        for(i = 0; i < strip->numPixels(); i++) {
            strip->setPixelColor(i, Wheel(strip, (i + j) & 255));
        }
        strip->show();
        delay(wait);
    }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(Adafruit_NeoPixel* strip, uint8_t wait) {
    uint16_t i, j;
    for(j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
        for(i=0; i< strip->numPixels(); i++) {
            strip->setPixelColor(i, Wheel(strip, ((i * 256 / strip->numPixels()) + j) & 255));
        }
        strip->show();
        delay(wait);
    }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(Adafruit_NeoPixel* strip, uint8_t wait) {
    for (int j = 0; j < 256; j++) {     // cycle all 256 colors in the wheel
        for (int q = 0; q < 3; q++) {
            for (uint16_t i = 0; i < strip->numPixels(); i = i + 3) {
                strip->setPixelColor(i + q, Wheel(strip, (i + j) % 255));    //turn every third pixel on
            }
            strip->show();

            delay(wait);

            for (uint16_t i = 0; i < strip->numPixels(); i = i + 3) {
                strip->setPixelColor(i + q, 0);        //turn every third pixel off
            }
        }
    }
}

void RainbowAnimation::drawFrame() {
    Adafruit_NeoPixel* strip = this->getStrip();
    rainbow(strip, 20);
    rainbowCycle(strip, 20);
    theaterChaseRainbow(strip, 50);
};
<|endoftext|>


<commit_before>_Pragma("once")<commit_msg>impl rotate operation<commit_after>_Pragma("once")
#include <memory>

struct Node;
using sptr = std::shared_ptr<Node>;
using wptr = std::weak_ptr<Node>;
struct Node {
public:
	int data;
	enum class ColorType {RED, BLACK} color;
	sptr left, right;
	wptr parent;
};

class RedBlackBST {
public:
private:
	void right_rotate(sptr x) {
		sptr y{x->left};
		// turn y's right subtree into x's left subtree
		x->left = y->right;
		// TODO: Could we cancel the condition (y->right != nil)?
		y->right->parent = x;
		// link x's parent to y
		y->parent = x->parent;
		sptr parent{x->parent.lock()};
		if (parent == nil) root = y;
		else if (x == parent->left) parent->left = y;
		else parent->right = y;
		y->right = x;
		x->parent = y;
	}

	void left_rotate(sptr x) {
		sptr y{x->right};
		// turn y's left subtree into x's right subtree
		x->right = y->left;
		y->left->parent = x;
		// link x's parent to y
		y->parent = x->parent;
		sptr parent{x->parent.lock()};
		if (parent == nil) root = y;
		else if (x == parent->left) parent->left = y;
		else parent->right = y;
		y->left = x;
		x->parent = y;
	}
	sptr root, nil;
};<|endoftext|>


<commit_before>#include <cstdio>

#define NIL 0

using namespace std;

struct node
{
	int key, value;
	node *ch[2];
	node(int _key = 0, int _value = 0) : key(_key), value(_value) { ch[0] = ch[1] = NIL; }
}*root;

void init_splay()
{
	root = new node();
}

void rotate(node *&u, int dir)
{
	node *o = u->ch[dir];
	u->ch[dir] = o->ch[dir ^ 1];
	o->ch[dir ^ 1] = u;
	u = o;
}

void insert(node *&u, int key, int value)
{
	if (u == NIL)
	{
		u = new node(key, value);
		return;
	}
	if (key < u->key)
	{
		if (u->ch[0] == NIL)
		{
			u->ch[0] = new node(key, value);
		}
		else
		{
			if (key < u->ch[0]->key)
			{
				insert(u->ch[0]->ch[0], key, value);
				rotate(u->ch[0], 0);
			}
			else if (key > u->ch[0]->key)
			{
				insert(u->ch[0]->ch[1], key, value);
				rotate(u->ch[0], 1);
			}
		}
		rotate(u, 0);
	}
	else if (key > u->key)
	{
		if (u->ch[1] == NIL)
		{
			u->ch[1] = new node(key, value);
		}
		else
		{
			if (key < u->ch[1]->key)
			{
				insert(u->ch[1]->ch[0], key, value);
				rotate(u->ch[1], 0);
			}
			else if (key > u->ch[1]->key)
			{
				insert(u->ch[1]->ch[1], key, value);
				rotate(u->ch[1], 1);
			}
		}
		rotate(u, 1);
	}
}

int find(node *&u, int key)
{
	int res;
	if (u == NIL)
	{
		return -1;
	}
	if (u->key == key)
	{
		res = u->value;
	}
	if (key < u->key)
	{
		if (u->ch[0] == NIL)
		{
			return -1;
		}
		if (u->ch[0]->key == key)
		{
			res = u->ch[0]->value;
		}
		if (key < u->ch[0]->key)
		{
			res = find(u->ch[0]->ch[0], key);
			if (u->ch[0]->ch[0] != NIL)
			{
				rotate(u->ch[0], 0);
			}
		}
		else if (key > u->ch[0]->key);
		{
			res = find(u->ch[0]->ch[1], key);
			if (u->ch[0]->ch[1] != NIL)
			{
				rotate(u->ch[0], 1);
			}
		}
		rotate(u, 0);
	}
	else if (key > u->key)
	{
		if (u->ch[1] == NIL)
		{
			return -1;
		}
		if (u->ch[1]->key == key)
		{
			res = u->ch[1]->value;
		}
		if (key < u->ch[1]->key)
		{
			res = find(u->ch[1]->ch[0], key);
			if (u->ch[1]->ch[0] != NIL)
			{
				rotate(u->ch[1], 0);
			}
		}
		else if (key > u->ch[1]->key)
		{
			res = find(u->ch[1]->ch[1], key);
			if (u->ch[1]->ch[1] != NIL)
			{
				rotate(u->ch[1], 1);
			}
		}
		rotate(u, 1);
	}
	return res;
}

void DFS(node *u)
{
	printf("node : key = %d, value = %d\n", u->key, u->value);
	if (u->ch[0] != NIL)
	{
		printf("left child:\n");
		DFS(u->ch[0]);
	}
	if (u->ch[1] != NIL)
	{
		printf("right child:\n");
		DFS(u->ch[1]);
	}
}

int main()
{
	int in, key, value;
	while (true)
	{
		scanf("%d", &in);
		if (in == 1)
		{
			scanf("%d%d", &key, &value);
			insert(root, key, value);
		}
		else if (in == 2)
		{
			scanf("%d", &key);
			printf("%d\n", find(root, key));
		}
		else if (in == 4)
		{
			DFS(root);
		}
		else if (in == 0)
		{
			return 0;
		}
		else
		{
			printf("No such command!\n");
		}
	}
	return 0;
}
<commit_msg>修正了错误的伸展操作并简化代码<commit_after>#include <cstdio>

#define NIL 0

using namespace std;

struct node
{
	int key, value;
	node *ch[2];
	node(int _key = 0, int _value = 0) : key(_key), value(_value) { ch[0] = ch[1] = NIL; }
}*root;

void rotate(node *&u, int dir)
{
	node *o = u->ch[dir];
	u->ch[dir] = o->ch[dir ^ 1];
	o->ch[dir ^ 1] = u;
	u = o;
}

inline int compare(node *u, int key)
{
	if (key == u->key)
	{
		return -1;
	}
	return key < u->key ? 0 : 1;
}

void insert(node *&u, int key, int value)
{
	if (u == NIL)
	{
		u = new node(key, value);
		return;
	}
	int k0 = compare(u, key);
	if (k0 == -1)
	{
		return;
	}
	if (u->ch[k0] == NIL)
	{
		u->ch[k0] = new node(key, value);
	}
	else
	{
		int k1 = compare(u->ch[k0], key);
		if (k1 == -1)
		{
			return;
		}
		insert(u->ch[k0]->ch[k1], key, value);
		if (k0 == k1)
		{
			rotate(u, k0);
		}
		else
		{
			rotate(u->ch[k0], k1);
		}
	}
	rotate(u, k0);
}

int find(node *&u, int key)
{
	if (u == NIL)
	{
		return -1;
	}
	int k0 = compare(u, key);
	if (k0 == -1)
	{
		return u->value;
	}
	if (u->ch[k0] == NIL)
	{
		return -1;
	}
	else
	{
		int k1 = compare(u->ch[k0], key), res;
		if (k1 == -1)
		{
			res = u->ch[k0]->value;
			goto END;
		}
		res = find(u->ch[k0]->ch[k1], key);
		if (u->ch[k0]->ch[k1] != NIL)
		{
			if (k0 == k1)
			{
				rotate(u, k0);
			}
			else
			{
				rotate(u->ch[k0], k1);
			}
		}
	END:
		rotate(u, k0);
		return res;
	}
}

int main()
{
	int in, key, value;
	while (true)
	{
		scanf("%d", &in);
		if (in == 1)
		{
			scanf("%d%d", &key, &value);
			insert(root, key, value);
		}
		else if (in == 2)
		{
			scanf("%d", &key);
			printf("%d\n", find(root, key));
		}
		else if (in == 0)
		{
			return 0;
		}
		else
		{
			printf("No such command!\n");
		}
	}
	return 0;
}
<|endoftext|>


<commit_before>//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#define LOG_TAG "ArmnnDriver"

#include "Utils.hpp"

#include <armnnUtils/Permute.hpp>

#include <armnn/Utils.hpp>

#include <cassert>
#include <cinttypes>

using namespace android;
using namespace android::hardware;
using namespace android::hidl::memory::V1_0;

namespace armnn_driver
{
const armnn::PermutationVector g_DontPermute{};

namespace
{

void SwizzleAndroidNn4dTensorToArmNn(const armnn::TensorShape& inTensorShape, const void* input,
                                     void* output, size_t dataTypeSize, const armnn::PermutationVector& mappings)
{
    assert(inTensorShape.GetNumDimensions() == 4U);

    armnnUtils::Permute(armnnUtils::Permuted(inTensorShape, mappings), mappings, input, output, dataTypeSize);
}

} // anonymous namespace

void SwizzleAndroidNn4dTensorToArmNn(const armnn::TensorInfo& tensor, const void* input, void* output,
                                     const armnn::PermutationVector& mappings)
{
    assert(tensor.GetNumDimensions() == 4U);

    armnn::DataType dataType = tensor.GetDataType();
    switch (dataType)
    {
    case armnn::DataType::Float16:
    case armnn::DataType::Float32:
    case armnn::DataType::QAsymmU8:
    case armnn::DataType::QSymmS8:
        SwizzleAndroidNn4dTensorToArmNn(tensor.GetShape(), input, output, armnn::GetDataTypeSize(dataType), mappings);
        break;
    default:
        ALOGW("Unknown armnn::DataType for swizzling");
        assert(0);
    }
}

void* GetMemoryFromPool(DataLocation location, const std::vector<android::nn::RunTimePoolInfo>& memPools)
{
    // find the location within the pool
    assert(location.poolIndex < memPools.size());

    const android::nn::RunTimePoolInfo& memPool = memPools[location.poolIndex];

    // Type android::nn::RunTimePoolInfo has changed between Android O and Android P, where
    // "buffer" has been made private and must be accessed via the accessor method "getBuffer".
#if defined(ARMNN_ANDROID_P) || defined(ARMNN_ANDROID_Q) // Use the new Android implementation.
    uint8_t* memPoolBuffer = memPool.getBuffer();
#else // Fallback to the old Android O implementation.
    uint8_t* memPoolBuffer = memPool.buffer;
#endif

    uint8_t* memory = memPoolBuffer + location.offset;

    return memory;
}

armnn::TensorInfo GetTensorInfoForOperand(const V1_0::Operand& operand)
{
    armnn::DataType type;

    switch (operand.type)
    {
        case V1_0::OperandType::TENSOR_FLOAT32:
            type = armnn::DataType::Float32;
            break;
        case V1_0::OperandType::TENSOR_QUANT8_ASYMM:
            type = armnn::DataType::QAsymmU8;
            break;
        case V1_0::OperandType::TENSOR_INT32:
            type = armnn::DataType::Signed32;
            break;
        default:
            throw UnsupportedOperand<V1_0::OperandType>(operand.type);
    }

    armnn::TensorInfo ret(operand.dimensions.size(), operand.dimensions.data(), type);

    ret.SetQuantizationScale(operand.scale);
    ret.SetQuantizationOffset(operand.zeroPoint);

    return ret;
}

#ifdef ARMNN_ANDROID_NN_V1_2 // Using ::android::hardware::neuralnetworks::V1_2

armnn::TensorInfo GetTensorInfoForOperand(const V1_2::Operand& operand)
{
    using namespace armnn;
    bool perChannel = false;

    DataType type;
    switch (operand.type)
    {
        case V1_2::OperandType::TENSOR_FLOAT32:
            type = armnn::DataType::Float32;
            break;
        case V1_2::OperandType::TENSOR_FLOAT16:
            type = armnn::DataType::Float16;
            break;
        case V1_2::OperandType::TENSOR_QUANT8_ASYMM:
            type = armnn::DataType::QAsymmU8;
            break;
        case V1_2::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
            perChannel=true;
            ARMNN_FALLTHROUGH;
        case V1_2::OperandType::TENSOR_QUANT8_SYMM:
            type = armnn::DataType::QSymmS8;
            break;
        case V1_2::OperandType::TENSOR_QUANT16_SYMM:
            type = armnn::DataType::QSymmS16;
            break;
        case V1_2::OperandType::TENSOR_INT32:
            type = armnn::DataType::Signed32;
            break;
        default:
            throw UnsupportedOperand<V1_2::OperandType>(operand.type);
    }

    TensorInfo ret(operand.dimensions.size(), operand.dimensions.data(), type);
    if (perChannel)
    {
        // ExtraParams is expected to be of type channelQuant
        BOOST_ASSERT(operand.extraParams.getDiscriminator() ==
                     V1_2::Operand::ExtraParams::hidl_discriminator::channelQuant);

        auto perAxisQuantParams = operand.extraParams.channelQuant();

        ret.SetQuantizationScales(perAxisQuantParams.scales);
        ret.SetQuantizationDim(MakeOptional<unsigned int>(perAxisQuantParams.channelDim));
    }
    else
    {
        ret.SetQuantizationScale(operand.scale);
        ret.SetQuantizationOffset(operand.zeroPoint);
    }

    return ret;
}

#endif

std::string GetOperandSummary(const V1_0::Operand& operand)
{
    return android::hardware::details::arrayToString(operand.dimensions, operand.dimensions.size()) + " " +
        toString(operand.type);
}

#ifdef ARMNN_ANDROID_NN_V1_2 // Using ::android::hardware::neuralnetworks::V1_2

std::string GetOperandSummary(const V1_2::Operand& operand)
{
    return android::hardware::details::arrayToString(operand.dimensions, operand.dimensions.size()) + " " +
           toString(operand.type);
}

#endif

using DumpElementFunction = void (*)(const armnn::ConstTensor& tensor,
    unsigned int elementIndex,
    std::ofstream& fileStream);

namespace
{
template <typename ElementType, typename PrintableType = ElementType>
void DumpTensorElement(const armnn::ConstTensor& tensor, unsigned int elementIndex, std::ofstream& fileStream)
{
    const ElementType* elements = reinterpret_cast<const ElementType*>(tensor.GetMemoryArea());
    fileStream << static_cast<PrintableType>(elements[elementIndex]) << ",";
}

constexpr const char* MemoryLayoutString(const armnn::ConstTensor& tensor)
{
    const char* str = "";

    switch (tensor.GetNumDimensions())
    {
        case 4:  { str = "(BHWC) "; break; }
        case 3:  { str = "(HWC) "; break; }
        case 2:  { str = "(HW) "; break; }
        default: { str = ""; break; }
    }

    return str;
}
} // namespace

void DumpTensor(const std::string& dumpDir,
    const std::string& requestName,
    const std::string& tensorName,
    const armnn::ConstTensor& tensor)
{
    // The dump directory must exist in advance.
    const std::string fileName = boost::str(boost::format("%1%/%2%_%3%.dump") % dumpDir % requestName % tensorName);

    std::ofstream fileStream;
    fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);

    if (!fileStream.good())
    {
        ALOGW("Could not open file %s for writing", fileName.c_str());
        return;
    }

    DumpElementFunction dumpElementFunction = nullptr;

    switch (tensor.GetDataType())
    {
        case armnn::DataType::Float32:
        {
            dumpElementFunction = &DumpTensorElement<float>;
            break;
        }
        case armnn::DataType::QAsymmU8:
        {
            dumpElementFunction = &DumpTensorElement<uint8_t, uint32_t>;
            break;
        }
        case armnn::DataType::Signed32:
        {
            dumpElementFunction = &DumpTensorElement<int32_t>;
            break;
        }
        default:
        {
            dumpElementFunction = nullptr;
        }
    }

    if (dumpElementFunction != nullptr)
    {
        const unsigned int numDimensions = tensor.GetNumDimensions();

        const unsigned int batch = (numDimensions == 4) ? tensor.GetShape()[numDimensions - 4] : 1;

        const unsigned int height = (numDimensions >= 3)
                                    ? tensor.GetShape()[numDimensions - 3]
                                    : (numDimensions >= 2) ? tensor.GetShape()[numDimensions - 2] : 1;

        const unsigned int width = (numDimensions >= 3)
                                   ? tensor.GetShape()[numDimensions - 2]
                                   : (numDimensions >= 1) ? tensor.GetShape()[numDimensions - 1] : 0;

        const unsigned int channels = (numDimensions >= 3) ? tensor.GetShape()[numDimensions - 1] : 1;

        fileStream << "# Number of elements " << tensor.GetNumElements() << std::endl;
        fileStream << "# Dimensions " << MemoryLayoutString(tensor);
        fileStream << "[" << tensor.GetShape()[0];
        for (unsigned int d = 1; d < numDimensions; d++)
        {
            fileStream << "," << tensor.GetShape()[d];
        }
        fileStream << "]" << std::endl;

        for (unsigned int e = 0, b = 0; b < batch; ++b)
        {
            if (numDimensions >= 4)
            {
                fileStream << "# Batch " << b << std::endl;
            }
            for (unsigned int c = 0; c < channels; c++)
            {
                if (numDimensions >= 3)
                {
                    fileStream << "# Channel " << c << std::endl;
                }
                for (unsigned int h = 0; h < height; h++)
                {
                    for (unsigned int w = 0; w < width; w++, e += channels)
                    {
                        (*dumpElementFunction)(tensor, e, fileStream);
                    }
                    fileStream << std::endl;
                }
                e -= channels - 1;
                if (c < channels)
                {
                    e -= ((height * width) - 1) * channels;
                }
            }
            fileStream << std::endl;
        }
        fileStream << std::endl;
    }
    else
    {
        fileStream << "Cannot dump tensor elements: Unsupported data type "
            << static_cast<unsigned int>(tensor.GetDataType()) << std::endl;
    }

    if (!fileStream.good())
    {
        ALOGW("An error occurred when writing to file %s", fileName.c_str());
    }
}

void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
                                 const std::string& dumpDir,
                                 armnn::NetworkId networkId,
                                 const armnn::IProfiler* profiler)
{
    // Check if profiling is required.
    if (!gpuProfilingEnabled)
    {
        return;
    }

    // The dump directory must exist in advance.
    if (dumpDir.empty())
    {
        return;
    }

    BOOST_ASSERT(profiler);

    // Set the name of the output profiling file.
    const std::string fileName = boost::str(boost::format("%1%/%2%_%3%.json")
                                            % dumpDir
                                            % std::to_string(networkId)
                                            % "profiling");

    // Open the ouput file for writing.
    std::ofstream fileStream;
    fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);

    if (!fileStream.good())
    {
        ALOGW("Could not open file %s for writing", fileName.c_str());
        return;
    }

    // Write the profiling info to a JSON file.
    profiler->Print(fileStream);
}

bool IsDynamicTensor(const armnn::TensorInfo& outputInfo)
{
    // Dynamic tensors have at least one 0-sized dimension
    return outputInfo.GetNumElements() == 0u;
}

} // namespace armnn_driver
<commit_msg>IVGCVSW-4266 Dump float16 input/output tensors<commit_after>//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#define LOG_TAG "ArmnnDriver"

#include "Utils.hpp"
#include "Half.hpp"

#include <armnnUtils/Permute.hpp>

#include <armnn/Utils.hpp>

#include <cassert>
#include <cinttypes>

using namespace android;
using namespace android::hardware;
using namespace android::hidl::memory::V1_0;

namespace armnn_driver
{
const armnn::PermutationVector g_DontPermute{};

namespace
{

void SwizzleAndroidNn4dTensorToArmNn(const armnn::TensorShape& inTensorShape, const void* input,
                                     void* output, size_t dataTypeSize, const armnn::PermutationVector& mappings)
{
    assert(inTensorShape.GetNumDimensions() == 4U);

    armnnUtils::Permute(armnnUtils::Permuted(inTensorShape, mappings), mappings, input, output, dataTypeSize);
}

} // anonymous namespace

void SwizzleAndroidNn4dTensorToArmNn(const armnn::TensorInfo& tensor, const void* input, void* output,
                                     const armnn::PermutationVector& mappings)
{
    assert(tensor.GetNumDimensions() == 4U);

    armnn::DataType dataType = tensor.GetDataType();
    switch (dataType)
    {
    case armnn::DataType::Float16:
    case armnn::DataType::Float32:
    case armnn::DataType::QAsymmU8:
    case armnn::DataType::QSymmS8:
        SwizzleAndroidNn4dTensorToArmNn(tensor.GetShape(), input, output, armnn::GetDataTypeSize(dataType), mappings);
        break;
    default:
        ALOGW("Unknown armnn::DataType for swizzling");
        assert(0);
    }
}

void* GetMemoryFromPool(DataLocation location, const std::vector<android::nn::RunTimePoolInfo>& memPools)
{
    // find the location within the pool
    assert(location.poolIndex < memPools.size());

    const android::nn::RunTimePoolInfo& memPool = memPools[location.poolIndex];

    // Type android::nn::RunTimePoolInfo has changed between Android O and Android P, where
    // "buffer" has been made private and must be accessed via the accessor method "getBuffer".
#if defined(ARMNN_ANDROID_P) || defined(ARMNN_ANDROID_Q) // Use the new Android implementation.
    uint8_t* memPoolBuffer = memPool.getBuffer();
#else // Fallback to the old Android O implementation.
    uint8_t* memPoolBuffer = memPool.buffer;
#endif

    uint8_t* memory = memPoolBuffer + location.offset;

    return memory;
}

armnn::TensorInfo GetTensorInfoForOperand(const V1_0::Operand& operand)
{
    armnn::DataType type;

    switch (operand.type)
    {
        case V1_0::OperandType::TENSOR_FLOAT32:
            type = armnn::DataType::Float32;
            break;
        case V1_0::OperandType::TENSOR_QUANT8_ASYMM:
            type = armnn::DataType::QAsymmU8;
            break;
        case V1_0::OperandType::TENSOR_INT32:
            type = armnn::DataType::Signed32;
            break;
        default:
            throw UnsupportedOperand<V1_0::OperandType>(operand.type);
    }

    armnn::TensorInfo ret(operand.dimensions.size(), operand.dimensions.data(), type);

    ret.SetQuantizationScale(operand.scale);
    ret.SetQuantizationOffset(operand.zeroPoint);

    return ret;
}

#ifdef ARMNN_ANDROID_NN_V1_2 // Using ::android::hardware::neuralnetworks::V1_2

armnn::TensorInfo GetTensorInfoForOperand(const V1_2::Operand& operand)
{
    using namespace armnn;
    bool perChannel = false;

    DataType type;
    switch (operand.type)
    {
        case V1_2::OperandType::TENSOR_FLOAT32:
            type = armnn::DataType::Float32;
            break;
        case V1_2::OperandType::TENSOR_FLOAT16:
            type = armnn::DataType::Float16;
            break;
        case V1_2::OperandType::TENSOR_QUANT8_ASYMM:
            type = armnn::DataType::QAsymmU8;
            break;
        case V1_2::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
            perChannel=true;
            ARMNN_FALLTHROUGH;
        case V1_2::OperandType::TENSOR_QUANT8_SYMM:
            type = armnn::DataType::QSymmS8;
            break;
        case V1_2::OperandType::TENSOR_QUANT16_SYMM:
            type = armnn::DataType::QSymmS16;
            break;
        case V1_2::OperandType::TENSOR_INT32:
            type = armnn::DataType::Signed32;
            break;
        default:
            throw UnsupportedOperand<V1_2::OperandType>(operand.type);
    }

    TensorInfo ret(operand.dimensions.size(), operand.dimensions.data(), type);
    if (perChannel)
    {
        // ExtraParams is expected to be of type channelQuant
        BOOST_ASSERT(operand.extraParams.getDiscriminator() ==
                     V1_2::Operand::ExtraParams::hidl_discriminator::channelQuant);

        auto perAxisQuantParams = operand.extraParams.channelQuant();

        ret.SetQuantizationScales(perAxisQuantParams.scales);
        ret.SetQuantizationDim(MakeOptional<unsigned int>(perAxisQuantParams.channelDim));
    }
    else
    {
        ret.SetQuantizationScale(operand.scale);
        ret.SetQuantizationOffset(operand.zeroPoint);
    }

    return ret;
}

#endif

std::string GetOperandSummary(const V1_0::Operand& operand)
{
    return android::hardware::details::arrayToString(operand.dimensions, operand.dimensions.size()) + " " +
        toString(operand.type);
}

#ifdef ARMNN_ANDROID_NN_V1_2 // Using ::android::hardware::neuralnetworks::V1_2

std::string GetOperandSummary(const V1_2::Operand& operand)
{
    return android::hardware::details::arrayToString(operand.dimensions, operand.dimensions.size()) + " " +
           toString(operand.type);
}

#endif

using DumpElementFunction = void (*)(const armnn::ConstTensor& tensor,
    unsigned int elementIndex,
    std::ofstream& fileStream);

namespace
{
template <typename ElementType, typename PrintableType = ElementType>
void DumpTensorElement(const armnn::ConstTensor& tensor, unsigned int elementIndex, std::ofstream& fileStream)
{
    const ElementType* elements = reinterpret_cast<const ElementType*>(tensor.GetMemoryArea());
    fileStream << static_cast<PrintableType>(elements[elementIndex]) << ",";
}

constexpr const char* MemoryLayoutString(const armnn::ConstTensor& tensor)
{
    const char* str = "";

    switch (tensor.GetNumDimensions())
    {
        case 4:  { str = "(BHWC) "; break; }
        case 3:  { str = "(HWC) "; break; }
        case 2:  { str = "(HW) "; break; }
        default: { str = ""; break; }
    }

    return str;
}
} // namespace

void DumpTensor(const std::string& dumpDir,
    const std::string& requestName,
    const std::string& tensorName,
    const armnn::ConstTensor& tensor)
{
    // The dump directory must exist in advance.
    const std::string fileName = boost::str(boost::format("%1%/%2%_%3%.dump") % dumpDir % requestName % tensorName);

    std::ofstream fileStream;
    fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);

    if (!fileStream.good())
    {
        ALOGW("Could not open file %s for writing", fileName.c_str());
        return;
    }

    DumpElementFunction dumpElementFunction = nullptr;

    switch (tensor.GetDataType())
    {
        case armnn::DataType::Float32:
        {
            dumpElementFunction = &DumpTensorElement<float>;
            break;
        }
        case armnn::DataType::QAsymmU8:
        {
            dumpElementFunction = &DumpTensorElement<uint8_t, uint32_t>;
            break;
        }
        case armnn::DataType::Signed32:
        {
            dumpElementFunction = &DumpTensorElement<int32_t>;
            break;
        }
        case armnn::DataType::Float16:
        {
            dumpElementFunction = &DumpTensorElement<armnn::Half>;
            break;
        }
        default:
        {
            dumpElementFunction = nullptr;
        }
    }

    if (dumpElementFunction != nullptr)
    {
        const unsigned int numDimensions = tensor.GetNumDimensions();

        const unsigned int batch = (numDimensions == 4) ? tensor.GetShape()[numDimensions - 4] : 1;

        const unsigned int height = (numDimensions >= 3)
                                    ? tensor.GetShape()[numDimensions - 3]
                                    : (numDimensions >= 2) ? tensor.GetShape()[numDimensions - 2] : 1;

        const unsigned int width = (numDimensions >= 3)
                                   ? tensor.GetShape()[numDimensions - 2]
                                   : (numDimensions >= 1) ? tensor.GetShape()[numDimensions - 1] : 0;

        const unsigned int channels = (numDimensions >= 3) ? tensor.GetShape()[numDimensions - 1] : 1;

        fileStream << "# Number of elements " << tensor.GetNumElements() << std::endl;
        fileStream << "# Dimensions " << MemoryLayoutString(tensor);
        fileStream << "[" << tensor.GetShape()[0];
        for (unsigned int d = 1; d < numDimensions; d++)
        {
            fileStream << "," << tensor.GetShape()[d];
        }
        fileStream << "]" << std::endl;

        for (unsigned int e = 0, b = 0; b < batch; ++b)
        {
            if (numDimensions >= 4)
            {
                fileStream << "# Batch " << b << std::endl;
            }
            for (unsigned int c = 0; c < channels; c++)
            {
                if (numDimensions >= 3)
                {
                    fileStream << "# Channel " << c << std::endl;
                }
                for (unsigned int h = 0; h < height; h++)
                {
                    for (unsigned int w = 0; w < width; w++, e += channels)
                    {
                        (*dumpElementFunction)(tensor, e, fileStream);
                    }
                    fileStream << std::endl;
                }
                e -= channels - 1;
                if (c < channels)
                {
                    e -= ((height * width) - 1) * channels;
                }
            }
            fileStream << std::endl;
        }
        fileStream << std::endl;
    }
    else
    {
        fileStream << "Cannot dump tensor elements: Unsupported data type "
            << static_cast<unsigned int>(tensor.GetDataType()) << std::endl;
    }

    if (!fileStream.good())
    {
        ALOGW("An error occurred when writing to file %s", fileName.c_str());
    }
}

void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
                                 const std::string& dumpDir,
                                 armnn::NetworkId networkId,
                                 const armnn::IProfiler* profiler)
{
    // Check if profiling is required.
    if (!gpuProfilingEnabled)
    {
        return;
    }

    // The dump directory must exist in advance.
    if (dumpDir.empty())
    {
        return;
    }

    BOOST_ASSERT(profiler);

    // Set the name of the output profiling file.
    const std::string fileName = boost::str(boost::format("%1%/%2%_%3%.json")
                                            % dumpDir
                                            % std::to_string(networkId)
                                            % "profiling");

    // Open the ouput file for writing.
    std::ofstream fileStream;
    fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);

    if (!fileStream.good())
    {
        ALOGW("Could not open file %s for writing", fileName.c_str());
        return;
    }

    // Write the profiling info to a JSON file.
    profiler->Print(fileStream);
}

bool IsDynamicTensor(const armnn::TensorInfo& outputInfo)
{
    // Dynamic tensors have at least one 0-sized dimension
    return outputInfo.GetNumElements() == 0u;
}

} // namespace armnn_driver
<|endoftext|>