// File: /workspace/github_cpp_makefile_star2_O2/sagarvare[P]reinforcement-learning-rock-paper-scissor/main.cpp
// Function: main
int main(){
	int R = 3;//Number of steps back you want to remember
	int tot_states = pow(3,R); //Note, the total states will increase if comps states are included
	int initialize_from_previous = 1;
	string filename_previous = "filename.txt";
	string filename_logs = "game_play.log";

	// char valid_input[] = {'R','P','S','E'};
	string valid_input = "EPRS";

	//valid game play input: PRS
	string valid_move = "PRS";


	// typedef pair<int, int> Key;
	map < pair<int,int> , float> graph_state; //Check syntax for mapping from pair to a single transition number
	vector<int> out2 = decimal_to_ternary(101);
	int break_flag = 0;
	int old_state, new_state;//These contain the state numbers
	int counter = 0;//Number of moves played

	deque<int>  state_queue; //Contains the current state , i.e. last R moves
	char user_input;
	//Maybe add an option of initializing the 
	// graph from an earlier saved graph if available
	
	if (initialize_from_previous == 1){
		//Start My graph from the previous
		//Read the input?? Figure out how to save a map to and from the filename.txt
		//Use this to check it out
		cout << "Initialization from stored logs **NOT SUPPORTED** .This is just a tester inplace. I will add initializing logic later on.";

		//Go through the files and initialize the state_vector and the graph state appropriately.
		//Also make sure that the counter is also set appropriately
		string line;
		ifstream gameFile (filename_logs);
		if (gameFile.is_open() ) {
			while (getline(gameFile,line) ){
				string move; //Move is the read in 
				vector<string> results;
				results = parse_CSV(line);
				for (vector<string>::iterator i = results.begin(); i != results.end(); ++i){
					string move = *i;
					size_t found = valid_move.find(move);
					if (found!=string::npos && move != ""){
						//Add things to state_queue and make the game graph
						cout << "\n\ngoing to add:" << move;
						if (counter < R){
							int num_user_input = convert_user_input_to_num(valid_input, move[0]);
							state_queue.push_back(num_user_input);
						}else{ //There are more than R number of moves already done
							old_state = convert_queue_to_state(state_queue,R);
							int num_user_input = convert_user_input_to_num(valid_input, move[0]);
							state_queue.push_back(num_user_input); 
							state_queue.pop_front();
							new_state = convert_queue_to_state(state_queue,R);

							//Update the current graph
							if (graph_state.count(make_pair(old_state,new_state)) == 0){//Check syntax
								//This is a state that has not been seen before
								graph_state[make_pair(old_state,new_state)] = 1; //Check syntax
							}else{
								//This key is present
								graph_state[make_pair(old_state,new_state)]= 1 + graph_state[make_pair(old_state,new_state)]; //Check syntax
							}
						}
						counter++;

  					}
				}

				cout << "\n\n";
			}
			gameFile.close();
		}
		else{
			cout << "Unable to  open the FIle\n\n";
		}
	}


	
	//For generating random numbers
    mt19937 rng;
    rng.seed(random_device()());
    std::uniform_int_distribution<mt19937::result_type> dist6(1,3); // distribution in range [1, 6]

	//Open a file for logging all the users moves
	string file_name = "game_play.log";
	ofstream outfile;
	outfile.open(file_name, ios_base::app);

	//Open a file for logging all the computers moves
	string file_name_computer = "game_play_computer.log";
	ofstream outfile_computer;
	outfile_computer.open(file_name_computer, ios_base::app);

	//Open a file for logging the W/L numbers
	string file_name_WL = "game_WL_numbers.log";
	ofstream outfile_WL;
	outfile_WL.open(file_name_WL, ios_base::app);

	if (initialize_from_previous ==0){
	}
	int AI_loss = 0;
	int AI_wins = 0;
	int AI_draws = 0;



	while(break_flag == 0){
		cout << "\nEnter what you wanna play : R,P,S";
		cin >> user_input;

		// if (find(valid_input.begin(), valid_input.end(), user_input) != valid_input.end() ){
		if (valid_input.find(user_input) != string::npos){
			//Element part of valid input
			if (user_input == 'E'){
				//User wants to end the game
				cout << "\n\nThanks for playing";

				//Write the W/L numbers to logs
				outfile_WL << "wins:" << AI_wins<<"\n";
				outfile_WL << "draws:" << AI_draws <<"\n";
				outfile_WL << "loss:" << AI_loss << "\n";

				break_flag = 1;
				break;
			}
			outfile << user_input << ",";
			int num_user_input = convert_user_input_to_num(valid_input, user_input);
			//Else continue with normal game
			//Log the play, computer plays something, log the graph state and log the result
			

			//The first R moves are random
			if (counter < R){
				cout << "\n\n\n--------------------------------------ENTERING THE RANDOM PHASE!\n\n\n";
				//Computer plays something randomly
				char comp_move = valid_input[dist6(rng)];
				outfile_computer << comp_move << ",";

			    cout << "--------------------------------------------The computer played:" << comp_move << endl;

			    int result = check_result(num_user_input,comp_move);
				//Add the move to the queue
				state_queue.push_back(num_user_input);


				//Update who won
				if (user_won(user_input, comp_move) == 1 ){
					AI_loss ++;

				}else if (computer_won(user_input, comp_move) == 1){
					AI_wins ++;

				}else{
					AI_draws ++;
				}





			}else{
				// Implement a queue for appending the moves 
				// i.e. keep popping oldest and add the latest
				// all the states from the queue --> state transition --> update graph
				old_state = convert_queue_to_state(state_queue,R);
				// state_queue.push_back(num_user_input);
				// state_queue.pop_front();

				//currently old_state=new_state is NOT wrong
				//Because of an old bug that I corrected horribly
				//Now the bug is gone, but I am left with horrible code

				new_state = convert_queue_to_state(state_queue,R); 


				//Draw a random element from the graph before updating
				string possible_inputs = "PRS";
				int transition_counts[3];//Counts the previously seen transitions

				for (int char_temp = 0;char_temp<= 2;++char_temp){
					// Somehow temporarily append a number to a queue and then remove it
					// TO DO - Add some logic here
					deque<int> temp_queue(state_queue);//Assume temp_queue holds this 
					temp_queue.pop_back();
					// int num_char_temp = convert_user_input_to_num(valid_input, valid_input[char_temp+ 1]);
					temp_queue.push_back(char_temp);
					int possible_new_state;
					possible_new_state = convert_queue_to_state(temp_queue,R);
					transition_counts[char_temp] = graph_state[make_pair(old_state,possible_new_state)];
				}

				//transition counts holds the three transitions
				//Draw a random sample based on these probabilities of transition
				//Maybe just simply draw a random uniform and then use cdf concept
				float prior_count = 0.5;
				cout << "\n\n";
				for (int it =0;it<3;it++){
					cout << "\nCounts for playing the next one as:" << valid_input[it+ 1] << " is:" << transition_counts[it];
				}
				int int_comp_move= draw_sample(transition_counts,prior_count);
				//int_comp_move stores the computers move in integer value
				char exp_move = valid_input[int_comp_move];
				char comp_move = beating_move(exp_move);
				cout << "\n\n----------------------------------Computer played:"<< comp_move << "\n";
				//Update the state queue to keep track of this

				//print the old state and the new state
				state_queue.push_back(num_user_input);
				state_queue.pop_front();

				//Update the new state
				new_state = convert_queue_to_state(state_queue,R); 


				//Log the comp_move? Maybe......No harm right? Useless data but still...Debugging purposes?
				outfile_computer << comp_move << ",";

				//Update the current graph
				if (graph_state.count(make_pair(old_state,new_state)) == 0){//Check syntax
					//This is a state that has not been seen before
					graph_state[make_pair(old_state,new_state)] = 1; //Check syntax
				}else{
					//This key is present
					graph_state[make_pair(old_state,new_state)]= 1 + graph_state[make_pair(old_state,new_state)]; //Check syntax
				}

				//Update who won
				if (user_won(user_input, comp_move) ){
					AI_loss ++;

				}else if (computer_won(user_input, comp_move) ){
					AI_wins ++;

				}else{
					AI_draws ++;
				}



			}
			counter++;




			//Write the input to user game data





			//After every 100 data inputs, 
			//Save current graph 






			//If in the playing mode, pick an action based on the graph






			//Note down the result and keep doing statistical analysis






		}else{
			//Element not part of valid input
			cout << "Please enter a valid move";

		}
		// break_flag = 1;
	}
	return 0; 
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2fb8, %rsp           # imm = 0x2FB8
leaq 0x3b29(%rip), %rsi      # 0x6020
leaq -0x2a8(%rbp), %rdi
leaq -0x2fd8(%rbp), %rdx
callq 0x32a0
leaq 0x3b1c(%rip), %rsi      # 0x602d
leaq -0x228(%rbp), %rdi
leaq -0x2fd8(%rbp), %rdx
callq 0x32a0
leaq 0x3b10(%rip), %rsi      # 0x603b
leaq -0xa0(%rbp), %rdi
leaq -0x2fd8(%rbp), %rdx
callq 0x32a0
leaq 0x3af7(%rip), %rsi      # 0x603c
leaq -0x208(%rbp), %rdi
leaq -0x2fd8(%rbp), %rdx
callq 0x32a0
leaq -0xd8(%rbp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq -0x1e8(%rbp), %rdi
pushq $0x65
popq %rsi
callq 0x4a1d
leaq -0x180(%rbp), %rdi
callq 0x35be
movq 0x6a3a(%rip), %rdi      # 0x8fd0
leaq 0x3aa3(%rip), %rsi      # 0x6040
callq 0x21d0
leaq -0x1c40(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0x2fd8(%rbp), %rdi
leaq -0x228(%rbp), %rsi
pushq $0x8
popq %rdx
callq 0x22c0
leaq -0x2f60(%rbp), %rdi
callq 0x2060
testb %al, %al
je 0x28e7
movq $0x0, -0x38(%rbp)
leaq -0x5d8(%rbp), %r14
leaq -0x208(%rbp), %r12
leaq -0x8c8(%rbp), %r13
leaq -0x2fd8(%rbp), %rdi
leaq -0x1c50(%rbp), %rsi
callq 0x2040
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x2904
leaq -0x7c8(%rbp), %rax
movq %rax, -0x7d8(%rbp)
andq $0x0, -0x7d0(%rbp)
movb $0x0, -0x7c8(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x1d0(%rbp)
andq $0x0, -0x1c0(%rbp)
leaq -0x2e8(%rbp), %rbx
movq %rbx, %rdi
leaq -0x1c50(%rbp), %rsi
callq 0x2260
movq %r14, %rdi
movq %rbx, %rsi
callq 0x48ac
leaq -0x1d0(%rbp), %rdi
movq %r14, %rsi
callq 0x39bc
movq %r14, %rdi
callq 0x32dc
movq %rbx, %rdi
callq 0x20d0
movq -0x1d0(%rbp), %r15
cmpq -0x1c8(%rbp), %r15
je 0x28b0
leaq -0x5d8(%rbp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2260
movq %r12, %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x2360
cmpq $-0x1, %rax
je 0x289b
movq %rbx, %rdi
leaq 0x3c4b(%rip), %rsi      # 0x6322
callq 0x3307
testb %al, %al
je 0x289b
movq 0x68e5(%rip), %rdi      # 0x8fd0
leaq 0x39c8(%rip), %rsi      # 0x60ba
callq 0x21d0
movq %rax, %rdi
leaq -0x5d8(%rbp), %rsi
callq 0x21a0
cmpl $0x2, -0x38(%rbp)
jg 0x2756
leaq -0x2c8(%rbp), %r14
movq %r14, %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2260
movq -0x5d8(%rbp), %rax
movsbl (%rax), %esi
movq %r14, %rdi
callq 0x4d6b
movl %eax, %ebx
movq %r14, %rdi
callq 0x20d0
movl %ebx, -0x80(%rbp)
leaq -0x180(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x3314
jmp 0x2891
leaq -0x3d8(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x333e
movq %r13, %r14
leaq -0x3d8(%rbp), %rbx
movq %rbx, %rdi
pushq $0x3
popq %rsi
callq 0x4af4
movl %eax, -0x30(%rbp)
movq %rbx, %rdi
callq 0x3920
leaq -0x288(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2260
movq -0x5d8(%rbp), %rax
movsbl (%rax), %esi
leaq -0x288(%rbp), %r13
movq %r13, %rdi
callq 0x4d6b
movl %eax, %ebx
movq %r13, %rdi
callq 0x20d0
movl %ebx, -0x100(%rbp)
leaq -0x180(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x3314
leaq -0x180(%rbp), %rbx
movq %rbx, %rdi
callq 0x3412
movq %r14, %rdi
movq %rbx, %rsi
callq 0x333e
movq %r14, %r13
movq %r14, %rdi
pushq $0x3
popq %rsi
callq 0x4af4
movl %eax, %ebx
movq %r13, %rdi
callq 0x3920
shlq $0x20, %rbx
movl -0x30(%rbp), %r14d
orq %rbx, %r14
movq %r14, -0x80(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x3438
testq %rax, %rax
je 0x2877
movq %r14, -0x80(%rbp)
leaq -0xe0(%rbp), %rbx
movq %rbx, %rdi
leaq -0x80(%rbp), %rsi
callq 0x345c
movss (%rax), %xmm0
movss %xmm0, -0x30(%rbp)
movq %r14, -0x120(%rbp)
movq %rbx, %rdi
leaq -0x120(%rbp), %rsi
callq 0x345c
movss -0x30(%rbp), %xmm0
addss 0x3797(%rip), %xmm0     # 0x6008
movss %xmm0, (%rax)
jmp 0x2891
movq %r14, -0x80(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x345c
movl $0x3f800000, (%rax)     # imm = 0x3F800000
movq -0x38(%rbp), %rax
incl %eax
movq %rax, -0x38(%rbp)
leaq -0x5d8(%rbp), %rdi
callq 0x20d0
addq $0x20, %r15
jmp 0x2697
movq 0x6719(%rip), %rdi      # 0x8fd0
leaq 0x3a62(%rip), %rsi      # 0x6320
callq 0x21d0
leaq -0x1d0(%rbp), %rdi
callq 0x32dc
leaq -0x7d8(%rbp), %rdi
callq 0x20d0
leaq -0x5d8(%rbp), %r14
jmp 0x25fc
movq $0x0, -0x38(%rbp)
movq 0x66da(%rip), %rdi      # 0x8fd0
leaq 0x37cd(%rip), %rsi      # 0x60ca
callq 0x21d0
jmp 0x2910
leaq -0x2fd8(%rbp), %rdi
callq 0x2050
leaq -0x2fd8(%rbp), %rdi
callq 0x2070
leaq -0x1c50(%rbp), %rdi
callq 0x20d0
leaq -0x2fd8(%rbp), %rdi
callq 0x34c6
leaq -0x1c50(%rbp), %rdi
callq 0x351a
leaq -0x1c50(%rbp), %rdi
callq 0x2270
movl %eax, %esi
leaq -0x2fd8(%rbp), %rdi
callq 0x34d6
leaq -0x1c50(%rbp), %rdi
callq 0x3570
movq $0x1, -0x130(%rbp)
movq $0x3, -0x128(%rbp)
leaq 0x36aa(%rip), %rsi      # 0x602d
leaq -0x80(%rbp), %rdi
leaq -0x1c50(%rbp), %rdx
callq 0x32a0
leaq -0x1c50(%rbp), %rdi
callq 0x2300
leaq -0x1c50(%rbp), %rdi
leaq -0x80(%rbp), %rsi
pushq $0x1
popq %rdx
callq 0x20e0
leaq 0x372c(%rip), %rsi      # 0x60e5
leaq -0x120(%rbp), %rdi
leaq -0x7d8(%rbp), %rdx
callq 0x32a0
leaq -0x7d8(%rbp), %rdi
callq 0x2300
leaq -0x7d8(%rbp), %rdi
leaq -0x120(%rbp), %rsi
pushq $0x1
popq %rdx
callq 0x20e0
leaq 0x3707(%rip), %rsi      # 0x60fc
leaq -0x100(%rbp), %rdi
leaq -0x5d8(%rbp), %rdx
callq 0x32a0
leaq -0x5d8(%rbp), %rdi
callq 0x2300
leaq -0x5d8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
pushq $0x1
popq %rdx
callq 0x20e0
movq $0x0, -0x50(%rbp)
movq 0x6597(%rip), %r15      # 0x8fd0
leaq 0x38bf(%rip), %r13      # 0x62ff
leaq -0x1d0(%rbp), %r12
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movq %r15, %rdi
leaq 0x36b1(%rip), %rsi      # 0x6110
callq 0x21d0
movq 0x6575(%rip), %rdi      # 0x8fe0
leaq -0x29(%rbp), %rsi
callq 0x2250
movsbl -0x29(%rbp), %esi
leaq -0xa0(%rbp), %rdi
xorl %edx, %edx
callq 0x2240
cmpq $-0x1, %rax
jne 0x2a9d
movq %r15, %rdi
leaq 0x37ac(%rip), %rsi      # 0x6242
callq 0x21d0
jmp 0x2a55
movb -0x29(%rbp), %al
cmpb $0x45, %al
je 0x2ec5
movsbl %al, %esi
leaq -0x1c50(%rbp), %rdi
callq 0x2220
movq %rax, %rdi
movq %r13, %rsi
callq 0x21d0
leaq -0x268(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2260
movsbl -0x29(%rbp), %esi
leaq -0x268(%rbp), %rbx
movq %rbx, %rdi
callq 0x4d6b
movl %eax, %r14d
movq %rbx, %rdi
callq 0x20d0
movl %r14d, -0x48(%rbp)
cmpl $0x2, -0x38(%rbp)
jg 0x2bab
movq %r15, %rdi
leaq 0x3650(%rip), %rsi      # 0x615b
callq 0x21d0
leaq -0x130(%rbp), %rdi
leaq -0x2fd8(%rbp), %rsi
callq 0x3584
movq -0xa0(%rbp), %rcx
movsbl (%rcx,%rax), %r14d
leaq -0x7d8(%rbp), %rdi
movl %r14d, %esi
callq 0x2220
movq %rax, %rdi
movq %r13, %rsi
callq 0x21d0
movq %r15, %rdi
leaq 0x364f(%rip), %rsi      # 0x61a2
callq 0x21d0
movq %rax, %rdi
movl %r14d, %esi
callq 0x2220
movq %rax, %rdi
callq 0x20f0
movsbl -0x48(%rbp), %edi
movl %r14d, %esi
callq 0x4a98
leaq -0x180(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x3314
movsbl -0x29(%rbp), %edi
movl %r14d, %esi
callq 0x4e82
cmpl $0x1, %eax
jne 0x2e38
movq -0x50(%rbp), %rax
incl %eax
movq %rax, -0x50(%rbp)
jmp 0x2eb6
leaq -0x878(%rbp), %rbx
movq %rbx, %rdi
leaq -0x180(%rbp), %rsi
callq 0x333e
movq %rbx, %rdi
pushq $0x3
popq %rsi
callq 0x4af4
movl %eax, %r14d
movq %rbx, %rdi
callq 0x3920
leaq -0x388(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x333e
leaq -0x388(%rbp), %rbx
movq %rbx, %rdi
pushq $0x3
popq %rsi
callq 0x4af4
movq %rbx, %rdi
callq 0x3920
leaq -0x248(%rbp), %rdi
leaq 0x342a(%rip), %rsi      # 0x603c
movq %r12, %rdx
callq 0x32a0
movl %r14d, %ebx
xorl %eax, %eax
movl %eax, -0x44(%rbp)
cmpl $0x3, %eax
jge 0x2cb2
movq %r12, %rdi
leaq -0x180(%rbp), %rsi
callq 0x333e
movq %r12, %rdi
callq 0x3592
movq %r12, %rdi
leaq -0x44(%rbp), %rsi
callq 0x3314
leaq -0x828(%rbp), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x333e
movq %r13, %rdi
pushq $0x3
popq %rsi
callq 0x4af4
movl %eax, %r14d
movq %r13, %rdi
callq 0x3920
shlq $0x20, %r14
orq %rbx, %r14
movq %r14, -0x58(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x345c
cvttss2si (%rax), %eax
movslq -0x44(%rbp), %rcx
movl %eax, -0xac(%rbp,%rcx,4)
movq %r12, %rdi
callq 0x3920
movl -0x44(%rbp), %eax
incl %eax
jmp 0x2c1f
movq %r15, %rdi
leaq 0x3664(%rip), %rsi      # 0x6320
callq 0x21d0
xorl %r14d, %r14d
cmpq $0x3, %r14
je 0x2d12
movq %r15, %rdi
leaq 0x350f(%rip), %rsi      # 0x61e3
callq 0x21d0
movq -0xa0(%rbp), %rcx
movsbl 0x1(%rcx,%r14), %esi
movq %rax, %rdi
callq 0x2220
movq %rax, %rdi
leaq 0x3510(%rip), %rsi      # 0x6208
callq 0x21d0
movl -0xac(%rbp,%r14,4), %esi
incq %r14
movq %rax, %rdi
callq 0x2310
jmp 0x2cc4
leaq -0xac(%rbp), %rdi
movss 0x32e3(%rip), %xmm0     # 0x6004
callq 0x4da4
cltq
movq -0xa0(%rbp), %rcx
movsbl (%rcx,%rax), %edi
callq 0x4ef0
movl %eax, %r14d
movq %r15, %rdi
leaq 0x34c8(%rip), %rsi      # 0x620d
callq 0x21d0
movsbl %r14b, %esi
movq %rax, %rdi
movl %esi, -0x30(%rbp)
callq 0x2220
movq %rax, %rdi
leaq 0x35be(%rip), %rsi      # 0x6321
callq 0x21d0
leaq -0x180(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x3314
leaq -0x180(%rbp), %r14
movq %r14, %rdi
callq 0x3412
leaq -0x338(%rbp), %rdi
movq %r14, %rsi
callq 0x333e
leaq -0x338(%rbp), %r13
movq %r13, %rdi
pushq $0x3
popq %rsi
callq 0x4af4
movl %eax, %r14d
movq %r13, %rdi
callq 0x3920
leaq -0x7d8(%rbp), %rdi
movl -0x30(%rbp), %esi
callq 0x2220
movq %rax, %rdi
leaq 0x3533(%rip), %rsi      # 0x62ff
callq 0x21d0
shlq $0x20, %r14
orq %rbx, %r14
movq %r14, -0x1d0(%rbp)
leaq -0xe0(%rbp), %rdi
movq %r12, %rsi
callq 0x3438
testq %rax, %rax
je 0x2e4e
movq %r14, -0x1d0(%rbp)
leaq -0xe0(%rbp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x345c
movss (%rax), %xmm0
movss %xmm0, -0x5c(%rbp)
movq %r14, -0x58(%rbp)
movq %rbx, %rdi
leaq -0x58(%rbp), %rsi
callq 0x345c
movss -0x5c(%rbp), %xmm0
addss 0x31d6(%rip), %xmm0     # 0x6008
movss %xmm0, (%rax)
jmp 0x2e6a
movsbl -0x29(%rbp), %edi
movl %r14d, %esi
callq 0x4eb9
cmpl $0x1, %eax
jne 0x2e9b
incl -0x40(%rbp)
jmp 0x2eb6
movq %r14, -0x1d0(%rbp)
leaq -0xe0(%rbp), %rdi
movq %r12, %rsi
callq 0x345c
movl $0x3f800000, (%rax)     # imm = 0x3F800000
movsbl -0x29(%rbp), %edi
movl -0x30(%rbp), %esi
callq 0x4e82
testl %eax, %eax
je 0x2e86
movq -0x50(%rbp), %rax
incl %eax
movq %rax, -0x50(%rbp)
jmp 0x2ea3
movsbl -0x29(%rbp), %edi
movl -0x30(%rbp), %esi
callq 0x4eb9
testl %eax, %eax
je 0x2ea0
incl -0x40(%rbp)
jmp 0x2ea3
incl -0x3c(%rbp)
jmp 0x2eb6
incl -0x3c(%rbp)
leaq 0x3455(%rip), %r13      # 0x62ff
leaq -0x248(%rbp), %rdi
callq 0x20d0
movq -0x38(%rbp), %rax
incl %eax
movq %rax, -0x38(%rbp)
jmp 0x2a55
movq 0x6104(%rip), %rdi      # 0x8fd0
leaq 0x3260(%rip), %rsi      # 0x6133
callq 0x21d0
leaq 0x3269(%rip), %rsi      # 0x6148
leaq -0x5d8(%rbp), %rdi
callq 0x21d0
movq %rax, %rdi
movl -0x40(%rbp), %esi
callq 0x2310
leaq 0x3424(%rip), %rsi      # 0x6321
movq %rax, %rdi
callq 0x21d0
leaq 0x3242(%rip), %rsi      # 0x614e
leaq -0x5d8(%rbp), %rdi
callq 0x21d0
movq %rax, %rdi
movl -0x3c(%rbp), %esi
callq 0x2310
leaq 0x33f7(%rip), %rsi      # 0x6321
movq %rax, %rdi
callq 0x21d0
leaq 0x321c(%rip), %rsi      # 0x6155
leaq -0x5d8(%rbp), %rdi
callq 0x21d0
movq %rax, %rdi
movq -0x50(%rbp), %rsi
callq 0x2310
leaq 0x33c9(%rip), %rsi      # 0x6321
movq %rax, %rdi
callq 0x21d0
leaq -0x5d8(%rbp), %rdi
callq 0x2290
leaq -0x100(%rbp), %rdi
callq 0x20d0
leaq -0x7d8(%rbp), %rdi
callq 0x2290
leaq -0x120(%rbp), %rdi
callq 0x20d0
leaq -0x1c50(%rbp), %rdi
callq 0x2290
leaq -0x80(%rbp), %rdi
callq 0x20d0
leaq -0x180(%rbp), %rdi
callq 0x3920
leaq -0x1e8(%rbp), %rdi
callq 0x38e2
leaq -0xe0(%rbp), %rdi
callq 0x37e8
leaq -0x208(%rbp), %rdi
callq 0x20d0
leaq -0xa0(%rbp), %rdi
callq 0x20d0
leaq -0x228(%rbp), %rdi
callq 0x20d0
leaq -0x2a8(%rbp), %rdi
callq 0x20d0
xorl %eax, %eax
addq $0x2fb8, %rsp           # imm = 0x2FB8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x31fb
movq %rax, %rbx
jmp 0x320a
jmp 0x301c
movq %rax, %rbx
jmp 0x3216
movq %rax, %rbx
jmp 0x3222
jmp 0x302e
movq %rax, %rbx
jmp 0x322e
movq %rax, %rbx
jmp 0x323a
jmp 0x3051
jmp 0x3051
jmp 0x3051
jmp 0x3105
movq %rax, %rbx
jmp 0x31e1
movq %rax, %rbx
jmp 0x3243
movq %rax, %rbx
jmp 0x324f
movq %rax, %rbx
jmp 0x325b
movq %rax, %rbx
jmp 0x3273
movq %rax, %rbx
jmp 0x327f
movq %rax, %rbx
jmp 0x328b
movq %rax, %rbx
leaq -0x1c50(%rbp), %rdi
callq 0x3570
jmp 0x3243
jmp 0x31ea
jmp 0x31ea
jmp 0x31ea
jmp 0x31fb
movq %rax, %rbx
leaq -0x338(%rbp), %rdi
jmp 0x31a2
jmp 0x31ea
jmp 0x31ea
jmp 0x31ea
movq %rax, %rbx
leaq -0x388(%rbp), %rdi
jmp 0x30dd
movq %rax, %rbx
leaq -0x878(%rbp), %rdi
callq 0x3920
jmp 0x31fe
jmp 0x31fb
jmp 0x31a9
movq %rax, %rbx
leaq -0x2e8(%rbp), %rdi
jmp 0x31b8
jmp 0x31a9
movq %rax, %rbx
jmp 0x31d5
jmp 0x31ae
movq %rax, %rbx
leaq -0x268(%rbp), %rdi
jmp 0x31f4
jmp 0x31ae
jmp 0x31ae
jmp 0x31fb
jmp 0x31fb
movq %rax, %rbx
leaq -0x3d8(%rbp), %rdi
jmp 0x3159
movq %rax, %rbx
leaq -0x2c8(%rbp), %rdi
jmp 0x316a
jmp 0x31ae
movq %rax, %rbx
leaq -0x8c8(%rbp), %rdi
callq 0x3920
jmp 0x31b1
movq %rax, %rbx
leaq -0x288(%rbp), %rdi
callq 0x20d0
jmp 0x31b1
jmp 0x31fb
jmp 0x31fb
jmp 0x31ea
jmp 0x31ae
jmp 0x31ae
jmp 0x3187
jmp 0x3187
jmp 0x31ea
movq %rax, %rbx
jmp 0x319b
movq %rax, %rbx
leaq -0x828(%rbp), %rdi
callq 0x3920
leaq -0x1d0(%rbp), %rdi
callq 0x3920
jmp 0x31ed
movq %rax, %rbx
jmp 0x31bd
movq %rax, %rbx
leaq -0x5d8(%rbp), %rdi
callq 0x20d0
leaq -0x1d0(%rbp), %rdi
callq 0x32dc
leaq -0x7d8(%rbp), %rdi
callq 0x20d0
leaq -0x2fd8(%rbp), %rdi
callq 0x2070
leaq -0x1c50(%rbp), %rdi
jmp 0x323e
movq %rax, %rbx
leaq -0x248(%rbp), %rdi
callq 0x20d0
jmp 0x31fe
movq %rax, %rbx
leaq -0x5d8(%rbp), %rdi
callq 0x2290
leaq -0x100(%rbp), %rdi
callq 0x20d0
leaq -0x7d8(%rbp), %rdi
callq 0x2290
leaq -0x120(%rbp), %rdi
callq 0x20d0
leaq -0x1c50(%rbp), %rdi
callq 0x2290
leaq -0x80(%rbp), %rdi
callq 0x20d0
leaq -0x180(%rbp), %rdi
callq 0x3920
leaq -0x1e8(%rbp), %rdi
callq 0x38e2
leaq -0xe0(%rbp), %rdi
callq 0x37e8
leaq -0x208(%rbp), %rdi
callq 0x20d0
leaq -0xa0(%rbp), %rdi
callq 0x20d0
leaq -0x228(%rbp), %rdi
callq 0x20d0
leaq -0x2a8(%rbp), %rdi
callq 0x20d0
movq %rbx, %rdi
callq 0x2330
nop