1 //  This file is part of the computer game Kartofel.
2 //  Copyright (C) 2008 Pawel Aleksander Fedorynski <pfedor@fuw.edu.pl>
3 //
4 //  This program 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 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 
18 #ifndef KARTOFEL_GAME_H
19 #define KARTOFEL_GAME_H
20 
21 #include <vector>
22 #include <istream>
23 
24 #include "lines.h"
25 
26 namespace kartofel {
27 
28 using std::vector;
29 using std::istream;
30 
31 enum DotType {
32   REGULAR,
33   EXTRA_LIFE,
34 };
35 
36 struct Dot {
37   int x;
38   int y;
39   int r;
40   DotType type;
41   bool lit;
42   union {
43     struct DotRegular {
44       int nr;
45       bool last;
46     } regular;
47 
48     struct DotExtraLife {
49       bool used;
50     } extra_life;
51   } data;
52 };
53 
54 struct Level {
55   Lines lines;
56   vector<Dot> dots;
57   int starting_phi;
58   int max_time;
59   int multiplier;
60 };
61 
62 void LoadLevel(const string& filename, Level* level);
63 
64 struct Input {
65   bool left;
66   bool right;
67   bool accelerate;
68   bool deccelerate;
69   bool start;
70 };
71 
72 // Since how many cycles have the inputs been on.  E.g., if it's the third
73 // time "left" is set, then left_cnt will be 3.
74 struct AccumulatedInput {
AccumulatedInputAccumulatedInput75   AccumulatedInput()
76     : left_cnt(0), right_cnt(0),
77       accelerate_cnt(0), deccelerate_cnt(0),
78       start_cnt(0) { }
79 
80   int left_cnt;
81   int right_cnt;
82   int accelerate_cnt;
83   int deccelerate_cnt;
84   int start_cnt;
85 };
86 
87 enum ActionType {
88   DRAW,
89   END_LEVEL,
90   EXPLOSION,
91   HIDE_STARTER,
92   LIGHT_DOT,
93   SHOW_STARTER,
94   OUT_OF_TIME,
95 };
96 
97 enum {
98   STEP_PHI = 15,
99   STEP_PHI_STARTER = 5,
100   STEP_SPEED = 1,
101   MAX_SPEED = 20,
102   MIN_SPEED = 2,
103   LOGICAL_BOARD_WIDTH = 10000,
104   LOGICAL_BOARD_HEIGHT = 10000,
105   DEFAULT_MAX_TIME = 100000,
106   STARTING_LIVES = 5,
107   STEP_MILLISECONDS = 30,
108   STEP_TS = 10,
109 };
110 
111 struct Action {
112   ActionType type;
113   union {
114     struct ActionDraw {
115       int start_x;
116       int start_y;
117       int end_x;
118       int end_y;
119     } draw;
120 
121     struct ActionExplosion {
122       int x;
123       int y;
124     } explosion;
125 
126     struct ActionLightDot {
127       int dot_index;
128     } dot;
129 
130     struct ActionShowStarter {
131       int dot_index;
132       int phi;
133     } starter;
134   } data;
135 };
136 
137 class Game {
138 public:
139   Game();
140   void Advance(const Input& input, int timestamp, vector<Action>* actions);
141   void SetLevel(const Level& level, int level_num);
142   void GetDot(int dot_index, Dot* dot) const;
143   int GetX() const;
144   int GetY() const;
145   int GetPhi() const;
146   int GetLevelNum() const;
147   int GetScore() const;
148   int GetLives() const;
149   int GetTimeLeft() const;
150   int GetSpeed() const;
151   int GetCurrentTimestamp() const;
152   bool StarterShown() const;
153   bool Initialized() const;
154   void CheckDotHitOrIntersection(int from_x, int from_y,
155                                  int* to_x, int* to_y,
156                                  bool starting,
157                                  bool* intersection,
158                                  bool* hit, int* hit_dot_index) const;
159   bool AtLevelStart() const;
160   void AddScore(int sc);
161   int GetMinimumSpeedUsed() const;
162   int GetLevelMultiplier() const;
163 private:
164   void AdjustSpeedAndPhi();
165   void SetWaitingXY();
166   void ProcessInput(const Input& input, vector<Action>* actions);
167   void CalculateTargetXY(int dt, int* target_x, int* target_y) const;
168   bool DotHit(int from_x, int from_y, int to_x, int to_y, bool starting,
169               int* hit_x, int* hit_y, int* hit_dot_index) const;
170   void Move(int dt, bool starting, vector<Action>* actions);
171   void AddActionHideStarter(vector<Action>* actions);
172   void AddActionShowStarter(vector<Action>* actions, int dot_index, int phi);
173   void AddActionDraw(vector<Action>* actions, int start_x, int start_y,
174                      int end_x, int end_y);
175   void AddActionExplosion(vector<Action>* actions, int x, int y);
176   void AddActionLightDot(vector<Action>* actions, int dot_index);
177   void AddActionEndLevel(vector<Action>* actions);
178   void AddActionOutOfTime(vector<Action>* actions);
179   void UpdateAccumulatedInput(const Input& input);
180 
181   Lines lines_;
182   vector<Dot> dots_;
183   int current_dot_;
184   int last_regular_dot_;
185   bool waiting_;
186   int current_timestamp_;
187   int time_left_;
188   int score_;
189   int lives_;
190   int x_;
191   int y_;
192   int phi_;
193   int speed_;
194   int min_speed_used_;
195   int level_num_;
196   int level_multiplier_;
197   AccumulatedInput acc_input_;
198 };
199 
200 void DebugPrintAction(const Action& a);
201 void DebugPrintInput(const Input& input);
202 
203 }  // namespace kartofel
204 
205 #endif  // KARTOFEL_GAME_H
206