SpaceInvaders  1.0
Ebauche d'une réalisation d'un space invader
SpaceInavder_ML.cpp
Aller à la documentation de ce fichier.
1 
14 #include <iostream>
15 #include <stdexcept>
16 #include <string>
17 #include <vector>
18 #include <utility> // max()
19 #include "MyConst_ML.h"
20 #include "MyType_ML.h"
21 
22 #define classdef typedef
23 
24 using namespace std;
25 using namespace nsSpaceInvaderML;
26 namespace nsSpaceInvaderML
27 {
28 
29  void Colour (const string & Coul)
30  {
31  cout << "\033[" << Coul <<"m";
32 
33  }// Colour()
34 
35  void ClearScreen ()
36  {
37  cout << "\033[H\033[2J";
38 
39  } //ClearScreen()
40 
41  void GotoXY (unsigned X, unsigned Y)
42  {
43  cout << "\033[" << Y << ';' << X << "H";
44 
45  } // gotoxy()
46 
47  void DownShift (CVString & Space, Size_t CurrentLine)
48  {
49  for (Size_t i (CurrentLine); i > 0; --i)
50  Space [i] = Space [i - 1];
51  Space [0] = KEmptyLine;
52 
53  } // DownShift()
54 
55  bool IsDead (const CVString & Space, Size_t Line, Size_t Column,
56  char Who)
57  {
58  return Space [Line][Column] != Who &&
59  (Space [Line][Column] == KInsideInvader ||
60  Space [Line][Column] == KInsideMe);
61 
62  } // IsDead()
63 
64  bool Shoot (CVString & Space, Size_t Line, Size_t Middle,
65  char Projectile, char Who)
66  {
67  if (IsDead (Space, Line, Middle, Who))
68  {
69  Space [Line] = KEmptyLine;
70  return true;
71  }
72  Space [Line][Middle] =
73  KEmpty == Space [Line][Middle] ? Projectile : KEmpty;
74  return false;
75 
76  } // Shoot()
77 
78  bool ManageInvader (int & Increment, Size_t & CurrentLine,
79  Size_t & Beg, bool & ToShoot,
80  bool & Win, CVString & Space)
81  {
82  if ((Increment > 0 &&
83  (Beg + KInvadersSize == KSizeLine ||
84  Space [CurrentLine][Beg + KInvadersSize] != KEmpty))
85  ||
86  (Increment < 0 &&
87  (Beg == 0 ||
88  Space [CurrentLine][Beg - 1] != KEmpty)))
89  {
90  ++CurrentLine;
91  for (Size_t j (Beg); j < Beg + KInvadersSize; ++j)
92  {
93  if (KTorpedo == Space [CurrentLine][j])
94  {
95  Win = true;
96  Space [CurrentLine] = KEmptyLine;
97  return false;
98  }
99  }
100 
101  Increment *= -1;
102  DownShift (Space, CurrentLine);
103  if (Space.size () - 1 <= CurrentLine)
104  return true;
105  }
106  else
107  {
108  string ToShift (Space [CurrentLine].
109  substr (Increment > 0 ? 0 : 1,
110  KSizeLine - 1));
111  Space [CurrentLine] = (Increment > 0) ? ' ' + ToShift
112  : ToShift + ' ';
113  }
114  Beg +=Increment;
115  ToShoot = ! ToShoot;
116  if (ToShoot)
117  {
118  return Shoot (Space, CurrentLine + 1,
120  }
121 
122  return false;
123 
124  } // ManageInvaders()
125 
126  void Remove (CVString & Space, Size_t Line, Size_t Column)
127  {
128  char Form = Space [Line][Column];
129  for (Size_t j (Column); j < KSizeLine &&
130  Space [Line][j] == Form; ++j)
131  Space [Line][j] = KEmpty;
132  for (Size_t j (Column); j-- > 0 &&
133  Space [Line][j] == Form; )
134  Space [Line][j] = KEmpty;
135 
136  } // Remove()
137 
138  void RecomputeSpace (CVString & Space, bool & Win, bool & Lost)
139  {
140  for (Size_t i (0); i < KSizeSpace; ++i)
141  {
142  for (Size_t j (0); j < KSizeLine; ++j)
143  {
144  if (KTorpedo == Space [i][j])
145  {
146  if (i != 0)
147  {
148  if (KInsideInvader == Space [i - 1][j])
149  {
150  Remove (Space, i - 1, j);
151  Win = true;
152  }
153  else if (KMissile == Space [i - 1][j])
154  {
155  Space [i - 1][j] = KEmpty;
156  }
157  else
158  {
159  Space [i - 1][j] = KTorpedo;
160  }
161  Space [i][j] = KEmpty;
162  }
163  else
164  {
165  Space [i][j] = KEmpty;
166  }
167  }
168  else if (KMissile == Space [i][j])
169  {
170  /* le probleme est de ne pas faire avancer le missile de plus d'un */
171  if (i != KSizeSpace - 1)
172  {
173  if (KInsideMe == Space [i + 1][j])
174  {
175  Remove (Space, i + 1, j);
176  Lost = true;
177  Space [i][j] = KEmpty;
178  }
179  else if (KTorpedo == Space [i + 1][j])
180  {
181  Space [i + 1][j] = KEmpty;
182  Space [i][j] = KEmpty;
183  }
184  else
185  {
186  if (i > 0 && KMissile == Space[i - 1][j])
187  {
188  Space [i - 1][j] = KEmpty;
189  }
190  else
191  {
192  Space [i + 1][j] = KMissile;
193  }
194  }
195  }
196  else if (KMissile == Space [i - 1][j])
197  {
198  Space [i - 1][j] = KEmpty;
199  }
200  else
201  {
202  Space [i][j] = KEmpty;
203  }
204  }
205 
206  }
207  }
208  } // RecomputeSpace()
209 
210  void DisplaySpace (const CVString & Space)
211  {
212  ClearScreen ();
213  for (string Line : Space)
214  {
215  cout << Line.size ();
216  for (unsigned Col (0); Col < Line.size (); ++Col)
217  {
218  switch (Line [Col])
219  {
220  case KInsideMe :
221  case KTorpedo :
222  Colour (KYellow);
223  break;
224  case KInsideInvader :
225  case KMissile :
226  Colour (KGreen);
227  break;
228  }
229  cout << Line [Col];
230 
231  Colour (KReset);
232  }
233  cout << Line.size ();
234  cout << endl;
235  }
236 
237  } // DisplaySpace()
238 
239  bool ManageMe (CVString & Space, Size_t & Pos, bool & Lost)
240  {
241  char C;
242  cin >> C;
243 
244  Size_t Line = Space.size () - 1;
245  string NewLastLine = Space [Line];
246  switch (C)
247  {
248  case KLeft :
249  if (Pos > 0)
250  {
251  --Pos;
252  if (IsDead (Space, Line, Pos, KInsideMe))
253  {
254  NewLastLine = KEmptyLine;
255  Lost = true;
256  }
257  else
258  {
259  NewLastLine = Space [Line].substr (0, Pos) +
260  Space [Line].substr (Pos + 1) + ' ';
261  }
262  }
263  break;
264  case KRight :
265  if (Pos < KSizeLine - 1)
266  {
267  ++Pos;
268  if (IsDead (Space, Line, Pos, KInsideMe))
269  {
270  NewLastLine = KEmptyLine;
271  Lost = true;
272  }
273  else
274  {
275  NewLastLine = Space [Line].substr (0, Pos - 1) + ' ' +
276  Space [Line].substr (Pos - 1,
277  KSizeLine - Pos);
278  }
279  }
280  break;
281  case KShoot :
282  return Shoot (Space, Line - 1, Pos, KTorpedo, KInsideMe);
283  }
284  Space [Line] = NewLastLine;
285 
286  return false;
287 
288  } // ManageMe()
289 
290  void SpaceInvaders (void)
291  {
292  CVString Space (KSizeSpace, KEmptyLine);
293 
294  // Initialisation of Space
295  Space [0] = KEmptyLine.substr (0, KBegInvader) +
296  KInvadersForm +
297  KEmptyLine.substr (0,
299  - KInvadersSize);
300  Space [Space.size () - 1] = KEmptyLine.substr (0, KBegMe) + KMyForm +
301  KEmptyLine.substr
302  (0, KSizeLine - KBegMe - KMySize);
303 
304  int Direction = 1;
305  Size_t CurrentLine (0);
306  Size_t PosInvader (KBegInvader);
307  Size_t PosMe (KBegMe);
308 
309  bool IWin = false;
310  bool ILoose = false;
311  bool InvadersShoots = false;
312  DisplaySpace (Space);
313  GotoXY (10, 20);
314  for (;;)
315  {
316  for (unsigned i (max (2u, KRatioMeInvaders)); i-- > 0; )
317  {
318  if (!ManageMe (Space, PosMe, ILoose) && ! ILoose)
319  {
320  RecomputeSpace (Space, IWin, ILoose);
321  }
322  DisplaySpace (Space);
323  if (ILoose || IWin) break;
324  }
325  if (ILoose || IWin) break;
326  ILoose = ManageInvader (Direction, CurrentLine, PosInvader,
327  InvadersShoots, IWin, Space);
328  if (! IWin && ! ILoose)
329  RecomputeSpace (Space, IWin, ILoose);
330  DisplaySpace (Space);
331  if (ILoose || IWin) break;
332  }
333  if (IWin)
334  {
335  cout << "J'ai gagné" << endl;
336  }
337  else
338  {
339  cout << "J'ai perdu" << endl;
340  }
341 
342  } // SpaceInvaders()
343 
344 } // namespace
345 
const unsigned KRatioMeInvaders
Nombre de fois où c&#39;est le tour du joueur pour un tour de l&#39;envahisseur.
Definition: MyConst_AC.h:121
bool IsDead(const CVString &Space, Size_t Line, Size_t Column, char Who)
Renvoie vrai si le belligérant meurt.
void DownShift(CVString &Space, Size_t CurrentLine)
Descend l&#39;envahisseur d&#39;une ligne dans l&#39;espace.
bool ManageMe(CVString &Space, Size_t &Pos, bool &Lost)
Simule le jeu du joueur. C&#39;est ici que le joueur choisit ce qu&#39;il fait. S&#39;il décide de tirer...
const unsigned KBegMe
Numéro de colonne où commence le joueur.
Definition: MyConst_AC.h:147
const std::string KGreen("32")
Alias mettant en vert la couleur du texte du terminal.
void GotoXY(unsigned X, unsigned Y)
const unsigned KMySize
Nombre de caractères qui forment mon vaisseau.
Definition: MyConst_AC.h:115
void Remove(CVString &Space, Size_t Line, Size_t Column)
enlève de l&#39;espace le belligérant qui a perdu.
const unsigned KSizeSpace
Nombre de colonnes de l&#39;écran (de l&#39;espace).
Definition: MyConst_AC.h:137
const std::string KInvadersForm(KInvadersSize, KInsideInvader)
Alias forme d&#39;un envahisseur.
const char KMissile
Caractèrere formant le missile.
Definition: MyConst_AC.h:84
const std::string KReset("0")
Alias remetant la couleur du texte du terminal à sa valeur par défaut.
bool Shoot(CVString &Space, Size_t Line, Size_t Middle, char Projectile, char Who)
Simule le tir d&#39;un belligérant. Renvoie vrai si le belligérant a gagné (faux sinon).
void ClearScreen()
Fonction effaçant le contenu de l&#39;écran.
const char KLeft
Alias vers la touche servant à se déplacer à gauche.
Definition: MyConst_AC.h:63
const std::string KMyForm(KMySize, KInsideMe)
Alias forme d&#39;un joueur.
const char KEmpty
Alias vers une case vide à l&#39;écran.
Definition: MyConst_AC.h:128
const char KTorpedo
Caractèrere formant ma torpille.
Definition: MyConst_AC.h:110
const char KShoot
Alias vers la touche servant à lancer une torpille.
Definition: MyConst_AC.h:68
const char KInsideInvader
Caractèrere formant l&#39;envahisseur.
Definition: MyConst_AC.h:79
const std::string KYellow("33")
Alias mettant en jaune la couleur du texte du terminal.
void RecomputeSpace(CVString &Space, bool &Win, bool &Lost)
recalcule l&#39;espace (déplacement des torpilles et des missiles) à chaque fois qu&#39;un belligérant a joué...
const std::string KEmptyLine(KSizeLine, KEmpty)
Alias vers une ligne vide de l&#39;esapce.
void DisplaySpace(const CVString &Space)
Permet d&#39;afficher l&#39;espace de jeu.
const char KRight
Alias vers la touche servant à se déplacer à droite.
Definition: MyConst_AC.h:58
const unsigned KBegInvader
Numéro de colonne où commence l&#39;envahisseur.
Definition: MyConst_AC.h:142
const char KInsideMe
Caractèrere formant mon vaisseau.
Definition: MyConst_AC.h:105
const unsigned KInvadersSize
Nombre de caractères qui forment l&#39;envahisseur.
Definition: MyConst_AC.h:89
void Colour(const string &Coul)
std::vector< std::string > CVString
Alias vers le type de l&#39;écran (l&#39;espace, la matrice).
Definition: MyType_ML.h:19
bool ManageInvader(int &Increment, Size_t &CurrentLine, Size_t &Beg, bool &ToShoot, bool &Win, CVString &Space)
Simule le jeu de l&#39;envahisseur. C&#39;est ici que l&#39;envahisseur joue. En bout de ligne l&#39;envahisseur desc...
const Size_t KInvadersMiddle
Alias déplacement du milieu d&#39;un envahisseur.
Definition: MyConst_ML.h:56
const unsigned KSizeLine
Nombre de lignes de l&#39;écran (de l&#39;espace).
Definition: MyConst_AC.h:132
CVString::size_type Size_t
Alias vers le type des indices d&#39;un CVString.
Definition: MyType_ML.h:23
void SpaceInvaders(void)
simule le jeux