// File: /workspace/github_cpp_makefile_star2_O3/samuel500[P]NEAT/individual.cpp
// Function: Individual::mutate_add_connection(std::vector<Node*, std::allocator<Node*>>*, std::vector<Connection*, std::allocator<Connection*>>*)
bool Individual::mutate_add_connection(vector<Node*> *all_nodes, vector<Connection*> *all_connections){

	Node *in_node;
	Node *out_node;


	int i = 0; // counter in case no new connection is possible
	bool duplicate = false;

	vector<Connection*>::iterator conPtr;


	do{

		int in_node_id = randint(0, nodes.size()-(*out_size)-1);
		// cout << "ma1" << endl;

		in_node = nodes[in_node_id];
		// cout << "ma2" << endl;

		int out_node_id;

		do{

			out_node_id = randint(*in_size, nodes.size()-1);
			i++;

		}while(in_node_id==out_node_id);

		out_node = nodes[out_node_id];

		duplicate = false;

		for(conPtr=out_node->in_connections.begin(); conPtr != out_node->in_connections.end(); ++conPtr){

			if((*conPtr)->in_node==in_node) duplicate = true; // proposed connection already exists

		}
			// cout << "ma3" << endl;

		for(conPtr=out_node->out_connections.begin(); conPtr != out_node->out_connections.end(); ++conPtr){

			if((*conPtr)->out_node==in_node) duplicate = true; // proposed opposite connection already exists, prevents simple loops

		}


	}while(i<20 && duplicate==true);

	if(duplicate==true) return false; // couldn't find any new possible connection


	int new_innov_number;

	bool found = false;


	for(conPtr=all_connections->begin(); conPtr != all_connections->end(); ++conPtr){
		// give identical mutations same hist_marking
		// could also check for mutation hist gen? 
		// (https://www.cs.ucf.edu/~kstanley/neat.html#FAQ1  - see "record of innovation" Q
		if((*conPtr)->in_node->hist_marking==in_node->hist_marking && (*conPtr)->out_node->hist_marking==out_node->hist_marking){
			new_innov_number = (*conPtr)->hist_marking;
			found = true;
			break;
		}

	}

	if(!found){
		new_innov_number = *innov_num;
		(*innov_num)++;
	}

	Connection *new_connection = new Connection(in_node, out_node, new_innov_number, *generation);

	connections.push_back(new_connection);
	// (*all_connections).push_back(new_connection);
	// cout << "ma3" << endl;

	in_node->out_connections.push_back(new_connection);
	out_node->in_connections.push_back(new_connection);

	return true;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, -0x40(%rbp)
movq %rdi, %rbx
movq 0x18(%rdi), %rax
xorl %r13d, %r13d
movq 0x20(%rbx), %r14
subq %rax, %r14
movq 0x88(%rbx), %rax
shrq $0x3, %r14
subl (%rax), %r14d
callq 0x1040
cltd
idivl %r14d
movl %edx, %r15d
movslq %edx, %rax
movq 0x18(%rbx), %rcx
movq (%rcx,%rax,8), %rax
movq %rax, -0x30(%rbp)
movq 0x20(%rbx), %r12
movq 0x80(%rbx), %rax
movl (%rax), %r14d
subq 0x18(%rbx), %r12
shrq $0x3, %r12
callq 0x1040
subl %r14d, %r12d
cltd
idivl %r12d
addl %r14d, %edx
incl %r13d
cmpl %edx, %r15d
je 0x6071
movslq %edx, %rcx
movq 0x18(%rbx), %rax
movq (%rax,%rcx,8), %r12
movq 0x18(%r12), %rcx
movq 0x20(%r12), %rdx
xorl %r15d, %r15d
cmpq %rdx, %rcx
je 0x60d7
movq -0x30(%rbp), %r14
movq (%rcx), %rsi
cmpq %r14, (%rsi)
sete %sil
orb %sil, %r15b
addq $0x8, %rcx
cmpq %rdx, %rcx
jne 0x60bf
jmp 0x60db
movq -0x30(%rbp), %r14
movq 0x30(%r12), %rcx
movq 0x38(%r12), %rdx
cmpq %rdx, %rcx
je 0x60fe
movq (%rcx), %rsi
cmpq %r14, 0x8(%rsi)
sete %sil
orb %sil, %r15b
addq $0x8, %rcx
jmp 0x60e5
leal -0x1(%r13), %ecx
cmpl $0x12, %ecx
jg 0x6111
testb $0x1, %r15b
jne 0x6041
testb $0x1, %r15b
jne 0x620c
movq -0x40(%rbp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
cmpq %rcx, %rax
je 0x6151
movl 0x4(%r14), %edx
movq (%rax), %rsi
movq (%rsi), %rdi
cmpl %edx, 0x4(%rdi)
jne 0x6148
movq 0x8(%rsi), %rdi
movl 0x4(%rdi), %edi
cmpl 0x4(%r12), %edi
je 0x6161
addq $0x8, %rax
cmpq %rcx, %rax
jne 0x612f
movq 0x78(%rbx), %rax
movl (%rax), %ecx
movq %rcx, -0x30(%rbp)
incl %ecx
movl %ecx, (%rax)
jmp 0x6168
movl 0x1c(%rsi), %eax
movq %rax, -0x30(%rbp)
movl $0x28, %edi
callq 0x1100
movq %rax, %r13
movq 0x90(%rbx), %rax
movl (%rax), %r8d
movq %r13, %rdi
movq %r14, %rsi
movq %r12, %rdx
movq -0x30(%rbp), %rcx
callq 0x666a
movq %r13, -0x38(%rbp)
movq 0x68(%rbx), %rsi
cmpq 0x70(%rbx), %rsi
je 0x61a9
movq %r13, (%rsi)
addq $0x8, 0x68(%rbx)
jmp 0x61b9
addq $0x60, %rbx
leaq -0x38(%rbp), %rdx
movq %rbx, %rdi
callq 0x2bbe
movq 0x38(%r14), %rsi
cmpq 0x40(%r14), %rsi
je 0x61d1
movq -0x38(%rbp), %rax
movq %rax, (%rsi)
addq $0x8, 0x38(%r14)
jmp 0x61e1
addq $0x30, %r14
leaq -0x38(%rbp), %rdx
movq %r14, %rdi
callq 0x2bbe
movq 0x20(%r12), %rsi
cmpq 0x28(%r12), %rsi
je 0x61fc
movq -0x38(%rbp), %rax
movq %rax, (%rsi)
addq $0x8, 0x20(%r12)
jmp 0x620c
addq $0x18, %r12
leaq -0x38(%rbp), %rdx
movq %r12, %rdi
callq 0x2bbe
notb %r15b
andb $0x1, %r15b
movl %r15d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0x28, %esi
movq %r13, %rdi
callq 0x1110
movq %rbx, %rdi
callq 0x11a0
nop