1 /***************************************************************
2 *程序名称:2048
3 *内容摘要:练习
4 *其它说明:无
5 *当前版本:V1.0
6 *作 者:tbz
7 *完成日期:2014年5月8日
8 ***************************************************************/
9
10 #ifndef _GIRD_H_
11 #define _GIRD_H_
12
13 //实现4X4的方格,并提供移动、检测输赢等操作
14 class Grid
15 {
16 public:
17 explicit Grid();
18
19 void print();
20
21 void move(char action);
22
23 bool isWon();
24 bool isLost();
25
26 private:
27 int position[4][4];
28
29 //这四个函数原理一致
30 bool moveLeft();
31 bool moveRight();
32 bool moveUp();
33 bool moveDown();
34
35 //辅助函数
36 bool isExistEqual(int row, int column);
37 void generateEntry(int count);
38 int& at(int row, int column);
39 int random(int min, int max);
40 };
41
42 #endif
Grid.h
1 /***************************************************************
2 *程序名称:2048
3 *内容摘要:练习
4 *其它说明:无
5 *当前版本:V1.0
6 *作 者:tbz
7 *完成日期:2014年5月8日
8 ***************************************************************/
9
10 #include <iostream>
11 #include <cstdlib>
12 #include <ctime>
13 #include <iomanip>
14 #include "Grid.h"
15 using namespace std;
16
17 //从1开始计数
18 int& Grid::at(int row, int column)
19 {
20 return position[row-1][column-1];
21 }
22
23 //生成某范围的随机数
24 int Grid::random(int min, int max)
25 {
26 return ((rand() % (max-min+1)) + min);
27 }
28
29 //建立4X4表格,并初始化
30 Grid::Grid()
31 {
32 srand(time(0));
33 for (int row = 1; row <= 4; ++row)
34 for (int column = 1; column <= 4; ++column)
35 {
36 at(row, column) = 0;
37 }
38
39 //放置2个数
40 generateEntry(2);
41 }
42
43 //生成几个数,不重复
44 void Grid::generateEntry(int count)
45 {
46 int x = 0, y = 0, value = 0;
47 for (int i = 0; i < count; ++i)
48 {
49 bool valid = false;
50 while(!valid)
51 {
52 x = random(1, 4);
53 y = random(1, 4);
54 value = random(1, 2) * 2;
55 if (!at(x, y))
56 {
57 valid = true;
58 at(x, y) = value;
59 }
60 }
61 }
62 }
63
64 //视图绘制
65 void Grid::print()
66 {
67 cout << " ------------2048------------" << endl;
68 cout << " ____________________________" << endl;
69 for (int i = 1; i <= 4; ++i)
70 {
71 cout << "|";
72 for (int j = 1; j <= 4; ++j)
73 {
74 int temp = at(i, j);
75 if (temp)
76 cout << " " << setw(4) << temp << ". ";
77 else
78 cout << " " << setw(4) << ‘ ‘ << ". ";
79 }
80
81 cout << "|" << endl;
82 }
83 cout << " ----------------------------" << endl;
84 }
85
86 //按动作移动
87 void Grid::move(char action)
88 {
89 bool moved = false;
90 switch(action)
91 {
92 case ‘a‘:
93 case ‘A‘:
94 moved = moveLeft();
95 break;
96 case ‘d‘:
97 case ‘D‘:
98 moved = moveRight();
99 break;
100 case ‘w‘:
101 case ‘W‘:
102 moved = moveUp();
103 break;
104 case ‘s‘:
105 case ‘S‘:
106 moved = moveDown();
107 break;
108 }
109 if (moved)
110 generateEntry(1);
111 }
112
113 //检测
114 bool Grid::isWon()
115 {
116 for (int i = 1; i <= 4; ++i)
117 {
118 for (int j = 1; j <= 4; ++j)
119 {
120 if (at(i, j) == 2048)
121 return true;
122 }
123 }
124 return false;
125 }
126
127 bool Grid::isExistEqual(int row, int column)
128 {
129 bool ret = false;
130
131 //行检测
132 if (row == 1)
133 {
134 ret = (at(row, column) == at(row+1, column));
135 }
136 else if (row == 4)
137 {
138 ret = (at(row, column) == at(row-1, column));
139 }
140 else
141 {
142 ret = (at(row, column) == at(row-1, column)) && (at(row, column) == at(row+1, column));
143 }
144
145 //列检测
146 if (column == 1)
147 {
148 ret = (at(row, column) == at(row, column+1));
149 }
150 else if (column == 4)
151 {
152 ret = (at(row, column) == at(row, column-1));
153 }
154 else
155 {
156 ret = (at(row, column) == at(row, column-1)) && (at(row, column) == at(row, column+1));
157 }
158 return ret;
159 }
160
161 bool Grid::isLost()
162 {
163 for (int i = 1; i <= 4; ++i)
164 {
165 for (int j = 1; j <= 4; ++j)
166 {
167 if (!at(i, j))
168 return false;
169 else
170 {
171 if (isExistEqual(i, j))
172 return false;
173 }
174 }
175 }
176
177 return true;
178 }
179
180 //下
181 bool Grid::moveDown()
182 {
183 int top = 1, bottom = 4;
184 bool moved = false;
185
186 for (int column = 1; column <= 4; ++column)
187 {
188 //相同的数字合并
189 int last = 0, pos = 0;
190 for (int work = bottom; work >= top; --work)
191 {
192 if (at(work, column))
193 {
194 if (last)
195 if (at(work, column) == last)
196 {
197 at(work, column) = 0;
198 at(pos, column) *= 2;
199 moved = true;
200 last = 0;
201 pos = 0;
202 }
203 else
204 {
205 last = at(work, column);
206 pos = work;
207 }
208 else if (!last)
209 {
210 last = at(work, column);
211 pos = work;
212 }
213 }
214 }
215
216 //将数字往栈底挤
217 for (int work = bottom; work >= top; --work)
218 {
219 if (at(work, column))
220 {
221 for (int i = work; i <= bottom-1; ++i)
222 {
223 if (!at(i+1, column))
224 {
225 swap(at(i, column), at(i+1, column));
226 moved = true;
227 }
228 else break;
229 }
230 }
231 }
232 }
233
234 return moved;
235 }
236
237 //上
238 bool Grid::moveUp()
239 {
240 int top = 4, bottom = 1;
241 bool moved = false;
242
243 for (int column = 1; column <= 4; ++column)
244 {
245 //相同的数字合并
246 int last = 0, pos = 0;
247 for (int work = bottom; work <= top; ++work)
248 {
249 if (at(work, column))
250 {
251 if (last)
252 if (at(work, column) == last)
253 {
254 at(work, column) = 0;
255 at(pos, column) *= 2;
256 moved = true;
257 last = 0;
258 pos = 0;
259 }
260 else
261 {
262 last = at(work, column);
263 pos = work;
264 }
265 else if (!last)
266 {
267 last = at(work, column);
268 pos = work;
269 }
270 }
271 }
272
273 //将数字往底挤
274 for (int work = bottom; work <= top; ++work)
275 {
276 if (at(work, column))
277 {
278 for (int i = work; i >= bottom+1; --i)
279 {
280 if (!at(i-1, column))
281 {
282 swap(at(i, column), at(i-1, column));
283 moved = true;
284 }
285 else break;
286 }
287 }
288 }
289 }
290
291 return moved;
292 }
293
294 //左
295 bool Grid::moveLeft()
296 {
297 int top = 4, bottom = 1;
298 bool moved = false;
299
300 for (int row = 1; row <= 4; ++row)
301 {
302 //相同的数字合并
303 int last = 0, pos = 0;
304 for (int work = bottom; work <= top; ++work)
305 {
306 if (at(row, work))
307 {
308 if (last)
309 if (at(row, work) == last)
310 {
311 at(row, work) = 0;
312 at(row,pos) *= 2;
313 moved = true;
314 last = 0;
315 pos = 0;
316 }
317 else
318 {
319 last = at(row, work);
320 pos = work;
321 }
322 else if (!last)
323 {
324 last = at(row, work);
325 pos = work;
326 }
327 }
328 }
329
330 //将数字往底挤
331 for (int work = bottom; work <= top; ++work)
332 {
333 if (at(row, work))
334 {
335 for (int i = work; i >= bottom+1; --i)
336 {
337 if (!at(row, i-1))
338 {
339 swap(at(row, i), at(row, i-1));
340 moved = true;
341 }
342 else break;
343 }
344 }
345 }
346 }
347
348 return moved;
349 }
350
351
352 //右
353 bool Grid::moveRight()
354 {
355 int top = 1, bottom = 4;
356 bool moved = false;
357
358 for (int row = 1; row <= 4; ++row)
359 {
360 //相同的数字合并
361 int last = 0, pos = 0;
362 for (int work = bottom; work >= top; --work)
363 {
364 if (at(row, work))
365 {
366 if (last)
367 if (at(row, work) == last)
368 {
369 at(row, work) = 0;
370 at(row,pos) *= 2;
371 moved = true;
372 last = 0;
373 pos = 0;
374 }
375 else
376 {
377 last = at(row, work);
378 pos = work;
379 }
380 else if (!last)
381 {
382 last = at(row, work);
383 pos = work;
384 }
385 }
386 }
387
388 //将数字往底挤
389 for (int work = bottom; work >= top; --work)
390 {
391 if (at(row, work))
392 {
393 for (int i = work; i <= bottom-1; ++i)
394 {
395 if (!at(row, i+1))
396 {
397 swap(at(row, i), at(row, i+1));
398 moved = true;
399 }
400 else break;
401 }
402 }
403 }
404 }
405
406 return moved;
407 }
Grid.cpp
1 /***************************************************************
2 *程序名称:2048
3 *内容摘要:练习
4 *其它说明:无
5 *当前版本:V1.0
6 *作 者:tbz
7 *完成日期:2014年5月8日
8 ***************************************************************/
9
10 #include <cstdlib>
11 #include <conio.h>
12 #include "Grid.h"
13 #include <iostream>
14 using namespace std;
15
16 bool isNeed(char c)
17 {
18 switch (c)
19 {
20 case ‘a‘:case ‘s‘:case ‘d‘:case ‘w‘:
21 case ‘A‘:case ‘S‘:case ‘D‘:case ‘W‘:
22 return true;
23 }
24 return false;
25 }
26
27 int main(int argc, char const *argv[])
28 {
29 Grid game;
30
31 //game flow control
32 while (true)
33 {
34 system("cls");
35 game.print();
36 if (game.isWon())
37 {
38 cout << endl << "Congratulation! You won!" << endl;
39 cout << "Press any key to exit." << endl;
40 int pause;
41 cin >> pause;
42 return 0;
43 }
44
45 if (game.isLost())
46 break;
47
48 //Promt
49 cout << endl;
50 cout << "A -> Left, D -> Right, W -> Up, S -> Down. (K -> Exit)" << endl;
51 char input = getch();
52
53 if (input == ‘k‘)
54 return 0;
55 if (!isNeed(input)) continue;
56
57 game.move(input);
58 }
59
60 cout << "Sorry! You lose." << endl;
61 int pause;
62 cin >> pause;
63 return 0;
64 }
main.cpp
时间: 2024-10-14 14:46:09