1 | // |
2 | // KBlackBox |
3 | // |
4 | // A simple game inspired by an emacs module |
5 | // |
6 | /*************************************************************************** |
7 | * Copyright (c) 1999-2000, Robert Cimrman * |
8 | * cimrman3@students.zcu.cz * |
9 | * * |
10 | * Copyright (c) 2007, Nicolas Roffet * |
11 | * nicolas-kde@roffet.com * |
12 | * * |
13 | * * |
14 | * This program is free software; you can redistribute it and/or modify * |
15 | * it under the terms of the GNU General Public License as published by * |
16 | * the Free Software Foundation; either version 2 of the License, or * |
17 | * (at your option) any later version. * |
18 | * * |
19 | * This program is distributed in the hope that it will be useful, * |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
22 | * GNU General Public License for more details. * |
23 | * * |
24 | * You should have received a copy of the GNU General Public License * |
25 | * along with this program; if not, write to the * |
26 | * Free Software Foundation, Inc., * |
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * |
28 | ***************************************************************************/ |
29 | |
30 | #include "kbbgamedoc.h" |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | #include "kbbballsonboard.h" |
37 | #include "kbbtutorial.h" |
38 | |
39 | |
40 | |
41 | // |
42 | // Constructor / Destructor |
43 | // |
44 | |
45 | KBBGameDoc::KBBGameDoc(KBBMainWindow *parent, KBBTutorial* tutorial) : QObject(parent) |
46 | { |
47 | setRunning(false); |
48 | m_columns = 1; |
49 | m_rows = 1; |
50 | m_tutorial = tutorial; |
51 | |
52 | m_random.setSeed(0); |
53 | |
54 | m_balls = new KBBBallsOnBoard(this, m_columns, m_rows); |
55 | m_ballsPlaced = new KBBBallsOnBoard(this, m_columns, m_rows); |
56 | connect(m_ballsPlaced, SIGNAL(changes()), parent, SLOT(updateStats())); |
57 | } |
58 | |
59 | |
60 | |
61 | // |
62 | // Public |
63 | // |
64 | |
65 | int KBBGameDoc::columns() const |
66 | { |
67 | return m_columns; |
68 | } |
69 | |
70 | |
71 | void KBBGameDoc::gameOver() |
72 | { |
73 | // Clear |
74 | setRunning(false); |
75 | |
76 | // Compute final score |
77 | if (m_ballsPlaced->numberOfBallsNotIn(m_balls)>0) |
78 | setScore(SCORE_LOST); |
79 | } |
80 | |
81 | |
82 | bool KBBGameDoc::gameReallyStarted() |
83 | { |
84 | return m_gameReallyStarted; |
85 | } |
86 | |
87 | |
88 | bool KBBGameDoc::mayShootRay(const int incomingPosition) const |
89 | { |
90 | if (m_tutorial->isVisible() && !m_tutorial->mayShootRay(incomingPosition)) |
91 | return false; |
92 | else |
93 | return true; |
94 | } |
95 | |
96 | |
97 | void KBBGameDoc::newGame(int balls, int columns, int rows) |
98 | { |
99 | clean(columns, rows); |
100 | |
101 | // Puts the balls in the black box on random positions. |
102 | int boxPos; |
103 | for (int i = 0; i < balls; i++) { |
104 | do { |
105 | boxPos = m_random.getLong(m_columns * m_rows); |
106 | } while (m_balls->contains(boxPos)); |
107 | m_balls->add(boxPos); |
108 | } |
109 | } |
110 | |
111 | |
112 | int KBBGameDoc::numberOfBallsPlaced() |
113 | { |
114 | return m_ballsPlaced->count(); |
115 | } |
116 | |
117 | |
118 | int KBBGameDoc::numberOfBallsToPlace() |
119 | { |
120 | return m_balls->count(); |
121 | } |
122 | |
123 | |
124 | int KBBGameDoc::rows() const |
125 | { |
126 | return m_rows; |
127 | } |
128 | |
129 | |
130 | int KBBGameDoc::score() |
131 | { |
132 | return m_score; |
133 | } |
134 | |
135 | |
136 | int KBBGameDoc::shootRay( int borderPosition ) |
137 | { |
138 | int outgoingBorderPosition = m_balls->oppositeBorderPosition(borderPosition); |
139 | |
140 | if ((outgoingBorderPosition == HIT_POSITION) || (borderPosition == outgoingBorderPosition)) |
141 | setScore(m_score + SCORE_ONE); |
142 | else |
143 | setScore(m_score + SCORE_TWO); |
144 | |
145 | if (!m_tutorial->isVisible()) |
146 | setRunning(true); |
147 | emit updateStats(); |
148 | |
149 | return outgoingBorderPosition; |
150 | } |
151 | |
152 | |
153 | void KBBGameDoc::startTutorial() |
154 | { |
155 | clean(KBBTutorial::COLUMNS, KBBTutorial::ROWS); |
156 | m_balls->add(16); |
157 | m_balls->add(21); |
158 | m_balls->add(33); |
159 | m_tutorial->setStep(1); |
160 | m_tutorial->start(); |
161 | } |
162 | |
163 | |
164 | void KBBGameDoc::timeChanged() |
165 | { |
166 | setScore(m_score+1); |
167 | } |
168 | |
169 | |
170 | |
171 | // |
172 | // Private |
173 | // |
174 | |
175 | void KBBGameDoc::clean(const int columns, const int rows) |
176 | { |
177 | m_columns = columns; |
178 | m_rows = rows; |
179 | |
180 | // Clear |
181 | setRunning(false); |
182 | m_ballsPlaced->newBoard(m_columns, m_rows); |
183 | setScore(-1); // -1 because a signal "timeChanged" will be send at the beginning and the score will be set to 0. |
184 | |
185 | m_balls->newBoard(m_columns, m_rows); |
186 | } |
187 | |
188 | |
189 | void KBBGameDoc::setRunning(const bool r) |
190 | { |
191 | m_gameReallyStarted = r; |
192 | emit isRunning(r); |
193 | } |
194 | |
195 | |
196 | void KBBGameDoc::setScore( int n ) |
197 | { |
198 | if (n<1000) |
199 | m_score = n; |
200 | else |
201 | m_score = 999; |
202 | emit updateStats(); |
203 | } |
204 | |
205 | #include "kbbgamedoc.moc" |
206 | |