1 /* Operational Roles and Analysis for AIs
2    Copyright (C) 2005 Eric A. McDonald.
3 
4 Xconq is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.  See the file COPYING.  */
8 
9 /*! \file
10     \brief Operational Roles and Analysis for AIs
11 
12     Part of the AI API, Level 4.
13 
14     Provides an operational level AI implementation.
15 
16     \note Nothing in this file should ever be required to implement an AI;
17 	    everything here is optional.
18 
19 */
20 
21 namespace Xconq {
22 namespace AI {
23 
24 //! Types of Operational Roles
25 
26 enum OpRole_Type {
27     //! No operational role.
28     OR_NONE = 0,
29     //! Operate as a shuttle for other units.
30     OR_SHUTTLE,
31     //! Operate as a constructor for other units.
32     OR_CONSTRUCTOR,
33     /* (TODO: Insert new oproles here.) */
34     OR_Total
35 };
36 
37 //! Operational Role Outcomes
38 
39 enum OpRole_Outcome {
40     //! Oprole was invalid.
41     ORO_INVALID = 0,
42     //! Oprole executed with failures.
43     ORO_FAILED,
44     //! Oprole executed without failures.
45     ORO_OK,
46     //! Oprole executed a tactical handler.
47     ORO_HANDLED_TACTICAL
48     // TODO: Insert new oprole outcomes here.
49 };
50 
51 //! Operational Role
52 
53 struct OpRole {
54     /* Basic Info */
55     //! Unit ID
56     int id;
57     //! Type of Operational Role
58     OpRole_Type type;
59     /* Extended Info */
60     //! Dedication to role.
61     int dedication;
62     //! Execs this turn.
63     int execs_this_turn;
64     //! Failures this turn.
65     int fails_this_turn;
66     /* (TODO: Graft in tasks queue here.) */
67     /* Overhead */
68     //! Next oprole in pool.
69     OpRole *next;
70     //! Next oprole in hash bucket.
71     OpRole *next_by_type;
72     //! Back-pointer to side.
73     Side *side;
74 };
75 
76 
77 /* TEMPORARY: Side-related AI management.
78     Should be moved to new files in the future. */
79 
80 //! Per-side master AI structure.
81 
82 struct AI_Side {
83     /* Scorekeeper-related information. */
84     //! List of scorekeeper analyses.
85     AI_SKAnalysis *sk_analyses;
86     /* Operational roles. */
87     //! List of in-use opertional role nodes.
88     OpRole *oproles;
89     //! List of unused operational role nodes.
90     OpRole *oproles_free;
91     //! Hash buckets of operational role nodes.
92     OpRole **oprole_buckets;
93     /* Overhead. */
94     //! Back-pointer to side.
95     Side *side;
96 };
97 
98 //! Create/init master AI structure associated with a side.
99 extern void create_side_ai(Side *side);
100 //! Return master AI structure associated with a side.
101 extern AI_Side * get_side_ai(Side *side);
102 
103 /** Management of Operational Roles **/
104 
105 //! Number of OpRole nodes per allocation block.
106 #define OR_BLK_SZ	200
107 
108 //! Iterate through all oproles on a side.
109 
110 #define for_all_oproles(side,oprole) \
111     for ((oprole) = (get_side_ai(side) ? get_side_ai(side)->oproles : NULL); \
112 	 (oprole); (oprole) = (oprole)->next)
113 
114 //! Iterate through all oproles on a side for a given type.
115 
116 #define for_all_oproles_by_type(side,type,oprole) \
117     for ((oprole) = (get_side_ai(side) ? \
118 			get_side_ai(side)->oprole_buckets[type] : NULL); \
119 	 (oprole); (oprole) = (oprole)->next_by_type)
120 
121 //! Allocate a new block of oproles in pool.
122 extern void allocate_oproles(Side *side, int nodesnum = OR_BLK_SZ);
123 //! Acquire oprole.
124 extern OpRole *acquire_oprole(Side *side, int id, OpRole_Type type);
125 //! Release oprole.
126 extern void release_oprole(OpRole *oprole);
127 //! Find oprole associated with a particular unit ID.
128 extern OpRole *find_oprole(Side *side, int id);
129 
130 /** Handling of Operational Roles **/
131 
132 /* Construction */
133 
134 //! Choose utype to construct, and optionally return its relative worth.
135 extern int choose_utype_to_construct(OpRole *oprole, int *uscore);
136 //! Choose transport to construct given utype in.
137 extern Unit *choose_transport_to_construct_in(
138     int u2, Side *side, UnitView *uview, int upchain = FALSE);
139 //! Generate an appropriate construction task given constructor and utype.
140 extern Task *generate_construction_task(Unit *unit, int u2);
141 //! Choose a construction task to perform.
142 extern int choose_construction_or_repair(OpRole *oprole);
143 //! Handle constructor operational role.
144 extern OpRole_Outcome handle_constructor_oprole(OpRole *oprole);
145 
146 /* General Operational Role Handling */
147 
148 //! Evaluate an operational role.
149 extern void handle_oprole(OpRole *oprole);
150 //! Evaluate all operational roles on a side.
151 extern void handle_oproles(Side *side);
152 
153 } // namespace Xconq::AI
154 } // namespace Xconq
155