Freeciv21
Develop your civilization from humble roots to a global empire
spaceship.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include "shared.h" // TRUE, FALSE
15 
16 #include "spaceship.h"
17 
19  {19, 13, -1}, // -1 means none required
20  {19, 15, 0}, {19, 11, 0}, {19, 17, 1}, {19, 9, 2}, {19, 19, 3},
21  {17, 9, 4}, {17, 19, 5}, {21, 11, 2}, {21, 17, 3}, {15, 9, 6},
22  {15, 19, 7}, {23, 11, 8}, {23, 17, 9}, {13, 9, 10}, {13, 19, 11},
23  {11, 9, 14}, {11, 19, 15}, {9, 9, 16}, {9, 19, 17}, {7, 9, 18},
24  {7, 19, 19}, {19, 7, 4}, {19, 21, 5}, {19, 5, 22}, {19, 23, 23},
25  {21, 5, 24}, {21, 23, 25}, {23, 5, 26}, {23, 23, 27}, {5, 9, 20},
26  {5, 19, 21}};
27 
29  {21, 13, 0}, {24, 13, 12}, {21, 15, 1},
30  {24, 15, 13}, {21, 9, 8}, // or 4
31  {24, 9, 12}, {21, 19, 9}, // or 5
32  {24, 19, 13}, {21, 7, 22}, {24, 7, 28},
33  {21, 21, 23}, {24, 21, 29}, {21, 3, 26},
34  {24, 3, 28}, {21, 25, 27}, {24, 25, 29}};
35 
37  {16, 12, 0}, {16, 16, 1}, {14, 6, 10}, {12, 16, 15},
38  {12, 12, 14}, {14, 22, 11}, {8, 12, 18}, {8, 16, 19},
39  {6, 6, 20}, {4, 16, 31}, {4, 12, 30}, {6, 22, 21}};
40 
45 void spaceship_init(struct player_spaceship *ship)
46 {
47  ship->structurals = ship->components = ship->modules = 0;
48  BV_CLR_ALL(ship->structure);
49  ship->fuel = ship->propulsion = 0;
50  ship->habitation = ship->life_support = ship->solar_panels = 0;
51  ship->state = SSHIP_NONE;
52  ship->launch_year = 9999;
53 
54  ship->population = ship->mass = 0;
55  ship->support_rate = ship->energy_rate = ship->success_rate =
56  ship->travel_time = 0.0;
57 }
58 
63 {
64  int i;
65  int num = 0;
66 
67  for (i = 0; i < NUM_SS_STRUCTURALS; i++) {
68  if (BV_ISSET(ship->structure, i)) {
69  num++;
70  }
71  }
72 
73  return num;
74 }
75 
79 bool next_spaceship_component(struct player *pplayer,
80  struct player_spaceship *ship,
81  struct spaceship_component *fill)
82 {
83  Q_UNUSED(pplayer)
84  fc_assert_ret_val(fill != nullptr, false);
85 
86  if (ship->modules
87  > (ship->habitation + ship->life_support + ship->solar_panels)) {
88  /* "nice" governments prefer to keep success 100%;
89  * others build habitation first (for score?) (Thanks Massimo.)
90  */
91  fill->type =
92  (ship->habitation == 0) ? SSHIP_PLACE_HABITATION
93  : (ship->life_support == 0) ? SSHIP_PLACE_LIFE_SUPPORT
94  : (ship->solar_panels == 0) ? SSHIP_PLACE_SOLAR_PANELS
95  : ((ship->habitation < ship->life_support)
96  && (ship->solar_panels * 2
97  >= ship->habitation + ship->life_support + 1))
99  : (ship->solar_panels * 2 < ship->habitation + ship->life_support)
102  : ((ship->life_support <= ship->habitation)
103  && (ship->solar_panels * 2
104  >= ship->habitation + ship->life_support + 1))
107 
108  if (fill->type == SSHIP_PLACE_HABITATION) {
109  fill->num = ship->habitation + 1;
110  } else if (fill->type == SSHIP_PLACE_LIFE_SUPPORT) {
111  fill->num = ship->life_support + 1;
112  } else {
113  fill->num = ship->solar_panels + 1;
114  }
115  fc_assert(fill->num <= NUM_SS_MODULES / 3);
116 
117  return true;
118  }
119  if (ship->components > ship->fuel + ship->propulsion) {
120  if (ship->fuel <= ship->propulsion) {
121  fill->type = SSHIP_PLACE_FUEL;
122  fill->num = ship->fuel + 1;
123  } else {
125  fill->num = ship->propulsion + 1;
126  }
127  return true;
128  }
129  if (ship->structurals > num_spaceship_structurals_placed(ship)) {
130  /* Want to choose which structurals are most important.
131  Else we first want to connect one of each type of module,
132  then all placed components, pairwise, then any remaining
133  modules, or else finally in numerical order.
134  */
135  int req = -1;
136  int i;
137 
138  if (!BV_ISSET(ship->structure, 0)) {
139  // if we don't have the first structural, place that!
141  fill->num = 0;
142  return true;
143  }
144 
145  if (ship->habitation >= 1
146  && !BV_ISSET(ship->structure, modules_info[0].required)) {
147  req = modules_info[0].required;
148  } else if (ship->life_support >= 1
149  && !BV_ISSET(ship->structure, modules_info[1].required)) {
150  req = modules_info[1].required;
151  } else if (ship->solar_panels >= 1
152  && !BV_ISSET(ship->structure, modules_info[2].required)) {
153  req = modules_info[2].required;
154  } else {
155  for (i = 0; i < NUM_SS_COMPONENTS; i++) {
156  if ((i % 2 == 0 && ship->fuel > (i / 2))
157  || (i % 2 == 1 && ship->propulsion > (i / 2))) {
158  if (!BV_ISSET(ship->structure, components_info[i].required)) {
159  req = components_info[i].required;
160  break;
161  }
162  }
163  }
164  }
165  if (req == -1) {
166  for (i = 0; i < NUM_SS_MODULES; i++) {
167  if ((i % 3 == 0 && ship->habitation > (i / 3))
168  || (i % 3 == 1 && ship->life_support > (i / 3))
169  || (i % 3 == 2 && ship->solar_panels > (i / 3))) {
170  if (!BV_ISSET(ship->structure, modules_info[i].required)) {
171  req = modules_info[i].required;
172  break;
173  }
174  }
175  }
176  }
177  if (req == -1) {
178  for (i = 0; i < NUM_SS_STRUCTURALS; i++) {
179  if (!BV_ISSET(ship->structure, i)) {
180  req = i;
181  break;
182  }
183  }
184  }
185  // sanity:
186  fc_assert_ret_val(req >= 0, false);
187  fc_assert(!BV_ISSET(ship->structure, req));
188 
189  /* Now we want to find a structural we can build which leads to req.
190  This loop should bottom out, because everything leads back to s0,
191  and we made sure above that we do s0 first.
192  */
193  while (!BV_ISSET(ship->structure, structurals_info[req].required)) {
194  req = structurals_info[req].required;
195  }
197  fill->num = req;
198 
199  return true;
200  }
201 
202  return false;
203 }
#define BV_CLR_ALL(bv)
Definition: bitvector.h:62
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
@ SSHIP_PLACE_PROPULSION
Definition: fc_types.h:1100
@ SSHIP_PLACE_STRUCTURAL
Definition: fc_types.h:1098
@ SSHIP_PLACE_LIFE_SUPPORT
Definition: fc_types.h:1102
@ SSHIP_PLACE_SOLAR_PANELS
Definition: fc_types.h:1103
@ SSHIP_PLACE_FUEL
Definition: fc_types.h:1099
@ SSHIP_PLACE_HABITATION
Definition: fc_types.h:1101
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
int num_spaceship_structurals_placed(const struct player_spaceship *ship)
Count the number of structurals placed; that is, in ship->structure[].
Definition: spaceship.cpp:62
bool next_spaceship_component(struct player *pplayer, struct player_spaceship *ship, struct spaceship_component *fill)
Find (default) place for next spaceship component.
Definition: spaceship.cpp:79
void spaceship_init(struct player_spaceship *ship)
Initialize spaceship struct; could also be used to "cancel" a spaceship (eg, if/when capital-capture ...
Definition: spaceship.cpp:45
const struct sship_part_info structurals_info[NUM_SS_STRUCTURALS]
Definition: spaceship.cpp:18
const struct sship_part_info modules_info[NUM_SS_MODULES]
Definition: spaceship.cpp:36
const struct sship_part_info components_info[NUM_SS_COMPONENTS]
Definition: spaceship.cpp:28
#define NUM_SS_MODULES
Definition: spaceship.h:86
#define NUM_SS_COMPONENTS
Definition: spaceship.h:85
#define NUM_SS_STRUCTURALS
Definition: spaceship.h:84
@ SSHIP_NONE
Definition: spaceship.h:78
double energy_rate
Definition: spaceship.h:111
bv_spaceship_structure structure
Definition: spaceship.h:97
double success_rate
Definition: spaceship.h:112
double support_rate
Definition: spaceship.h:110
double travel_time
Definition: spaceship.h:113
enum spaceship_state state
Definition: spaceship.h:105
Definition: player.h:231
enum spaceship_place_type type
Definition: spaceship.h:129