1 /*
2 ===========================================================================
3 
4 Return to Castle Wolfenstein single player GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”).
8 
9 RTCW SP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 RTCW SP Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with RTCW SP Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 
30 /*****************************************************************************
31  * name:		be_ai_gen.c
32  *
33  * desc:		genetic selection
34  *
35  *
36  *****************************************************************************/
37 
38 #include "../qcommon/q_shared.h"
39 #include "l_memory.h"
40 #include "l_log.h"
41 #include "l_utils.h"
42 #include "l_script.h"
43 #include "l_precomp.h"
44 #include "l_struct.h"
45 #include "aasfile.h"
46 #include "botlib.h"
47 #include "be_aas.h"
48 #include "be_aas_funcs.h"
49 #include "be_interface.h"
50 #include "be_ai_gen.h"
51 
52 //===========================================================================
53 //
54 // Parameter:			-
55 // Returns:				-
56 // Changes Globals:		-
57 //===========================================================================
GeneticSelection(int numranks,float * rankings)58 int GeneticSelection( int numranks, float *rankings ) {
59 	float sum;
60 	int i, index;
61 
62 	sum = 0;
63 	for ( i = 0; i < numranks; i++ )
64 	{
65 		if ( rankings[i] < 0 ) {
66 			continue;
67 		}
68 		sum += rankings[i];
69 	} //end for
70 	if ( sum > 0 ) {
71 		//select a bot where the ones with the higest rankings have
72 		//the highest chance of being selected
73 		//sum *= random();
74 		for ( i = 0; i < numranks; i++ )
75 		{
76 			if ( rankings[i] < 0 ) {
77 				continue;
78 			}
79 			sum -= rankings[i];
80 			if ( sum <= 0 ) {
81 				return i;
82 			}
83 		} //end for
84 	} //end if
85 	  //select a bot randomly
86 	index = random() * numranks;
87 	for ( i = 0; i < numranks; i++ )
88 	{
89 		if ( rankings[index] >= 0 ) {
90 			return index;
91 		}
92 		index = ( index + 1 ) % numranks;
93 	} //end for
94 	return 0;
95 } //end of the function GeneticSelection
96 //===========================================================================
97 //
98 // Parameter:			-
99 // Returns:				-
100 // Changes Globals:		-
101 //===========================================================================
GeneticParentsAndChildSelection(int numranks,float * ranks,int * parent1,int * parent2,int * child)102 int GeneticParentsAndChildSelection( int numranks, float *ranks, int *parent1, int *parent2, int *child ) {
103 	float rankings[256], max;
104 	int i;
105 
106 	if ( numranks > 256 ) {
107 		botimport.Print( PRT_WARNING, "GeneticParentsAndChildSelection: too many bots\n" );
108 		*parent1 = *parent2 = *child = 0;
109 		return qfalse;
110 	} //end if
111 	for ( max = 0, i = 0; i < numranks; i++ )
112 	{
113 		if ( ranks[i] < 0 ) {
114 			continue;
115 		}
116 		max++;
117 	} //end for
118 	if ( max < 3 ) {
119 		botimport.Print( PRT_WARNING, "GeneticParentsAndChildSelection: too few valid bots\n" );
120 		*parent1 = *parent2 = *child = 0;
121 		return qfalse;
122 	} //end if
123 	memcpy( rankings, ranks, sizeof( float ) * numranks );
124 	//select first parent
125 	*parent1 = GeneticSelection( numranks, rankings );
126 	rankings[*parent1] = -1;
127 	//select second parent
128 	*parent2 = GeneticSelection( numranks, rankings );
129 	rankings[*parent2] = -1;
130 	//reverse the rankings
131 	max = 0;
132 	for ( i = 0; i < numranks; i++ )
133 	{
134 		if ( rankings[i] < 0 ) {
135 			continue;
136 		}
137 		if ( rankings[i] > max ) {
138 			max = rankings[i];
139 		}
140 	} //end for
141 	for ( i = 0; i < numranks; i++ )
142 	{
143 		if ( rankings[i] < 0 ) {
144 			continue;
145 		}
146 		rankings[i] = max - rankings[i];
147 	} //end for
148 	  //select child
149 	*child = GeneticSelection( numranks, rankings );
150 	return qtrue;
151 } //end of the function GeneticParentsAndChildSelection
152