效果不好,見(jiàn)諒,沒(méi)事就寫(xiě)了一個(gè)!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
/** * @author Routh * @main.c * @date 2014, 4, 26 */ #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> // console width #define CONSOLE_WIDTH 80 #define BOX_WIDTH 10 int BOX[4][4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; // the console output handle HANDLE c_handle; void setCursorPosition( short x, short y) { static COORD c; c.X = x; c.Y = y; SetConsoleCursorPosition(c_handle, c); } void drawTheGameBox() { printf ( "%15s■■■■■■■■■■■■■■■■■■■■■\n" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■■■■■■■■■■■■■■■■■■■■■\n" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■■■■■■■■■■■■■■■■■■■■■\n" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■■■■■■■■■■■■■■■■■■■■■\n" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■%8s■%8s■%8s■%8s■\n" , "" , "" , "" , "" , "" ); printf ( "%15s■■■■■■■■■■■■■■■■■■■■■\n" , "" ); } /** * get a random position: R * the x : 0xff & (R >> 4) * the y : 0x0f & R */ int random() { int i = 0, j = 0, _index = 0, rrr = 0; int rand_arr[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; srand ((unsigned) time (NULL)); // rand() for (i = 0; i < 4; i ++) { for (j = 0; j < 4; j ++) { if (BOX[i][j] == 0) { rand_arr[_index ++] = (0xff & i << 4) | (0xf & j); } } } if (_index == 0) { return -1; } return rand_arr[ rand () % _index]; } /** the clean array.**/ int * alogs( int item[]) { int i = 0, j = 0; int tep[4] = {0, 0, 0, 0}, tmp[4] = {0, 0, 0, 0}; for (i = 0; i < 4; i ++) { if (item[i] != 0) { tep[j ++] = item[i]; } } for (i = 0; i < 3; i ++) { if (tep[0] == 0) break ; if (tep[i] == tep[i + 1]) { tep[i] *= 2; tep[i + 1] = 0; } } j = 0; for (i = 0; i < 4; i ++) { if (tep[i] != 0) { tmp[j ++] = tep[i]; } } return ( int *)(&tmp); } /** BOX can move.*/ int validate( int item[]) { int i = 0; for (i = 0; i < 3; i ++) { if (item[i] != 0 && item[i] == item[i + 1]) return 1; if (item[i] == 0 && item[i + 1] != 0) return 1; } return 0; } int keydownControlx( int key) { int i = 0, j = 0; int *p; int tp[4] = {0, 0, 0, 0}; switch (key) { case 72: // up j = 0; for (i = 0; i < 4; i ++) { tp[0] = BOX[0][i]; tp[1] = BOX[1][i]; tp[2] = BOX[2][i]; tp[3] = BOX[3][i]; p = alogs(tp); if (!validate(tp)) j ++; BOX[0][i] = p[0]; BOX[1][i] = p[1]; BOX[2][i] = p[2]; BOX[3][i] = p[3]; } return j != 4; case 80: // down j = 0; for (i = 0; i < 4; i ++) { tp[0] = BOX[3][i]; tp[1] = BOX[2][i]; tp[2] = BOX[1][i]; tp[3] = BOX[0][i]; p = alogs(tp); if (!validate(tp)) j ++; BOX[3][i] = p[0]; BOX[2][i] = p[1]; BOX[1][i] = p[2]; BOX[0][i] = p[3]; } return j != 4; case 75: // left j = 0; for (i = 0; i < 4; i ++) { tp[0] = BOX[i][0]; tp[1] = BOX[i][1]; tp[2] = BOX[i][2]; tp[3] = BOX[i][3]; p = alogs(tp); if (!validate(tp)) j ++; BOX[i][0] = p[0]; BOX[i][1] = p[1]; BOX[i][2] = p[2]; BOX[i][3] = p[3]; } return j != 4; case 77: // right j = 0; for (i = 0; i < 4; i ++) { tp[0] = BOX[i][3]; tp[1] = BOX[i][2]; tp[2] = BOX[i][1]; tp[3] = BOX[i][0]; p = alogs(tp); if (!validate(tp)) j ++; BOX[i][3] = p[0]; BOX[i][2] = p[1]; BOX[i][1] = p[2]; BOX[i][0] = p[3]; } return j != 4; default : return 0; } return 0; } int main() { int i = 0, j = 0, r = 0; /** set the cursor, visible or invisible.*/ CONSOLE_CURSOR_INFO cci = {1, 0}; /** get the console output handle.*/ c_handle = GetStdHandle(STD_OUTPUT_HANDLE); // hide the cursor. SetConsoleCursorInfo(c_handle, &cci); // SetConsoleTextAttribute(c_handle, 0x3); //system("color 30"); drawTheGameBox(); r = random(); if ( rand () % 2 == 0) { BOX[0xff & ( r >> 4)][0xf & r] = 2; } else { BOX[0xff & ( r >> 4)][0xf & r] = 4; } for (i = 0; i < 4; i ++) { for (j = 0; j < 4; j ++) { if (BOX[i][j] == 0) continue ; setCursorPosition(17 + j * 8 + 2 + (j * 2), i * 4 + (i + 2)); //SetConsoleTextAttribute(c_handle, BOX[i][j]); printf ( "%d" , BOX[i][j]); } } // begin while (1) { Sleep(100); // key down. while (_kbhit()) { // the key down fun. if (!keydownControlx(_getch())) continue ; // clear the console and redraw. system ( "cls" ); SetConsoleTextAttribute(c_handle, 0x3); drawTheGameBox(); for (i = 0; i < 4; i ++) { for (j = 0; j < 4; j ++) { if (BOX[i][j] == 0) continue ; setCursorPosition(17 + j * 8 + 2 + (j * 2), i * 4 + (i + 2)); //SetConsoleTextAttribute(c_handle, BOX[i][j]); printf ( "%d" , BOX[i][j]); } } r = random(); if ( r == -1 ) { // game over //SetConsoleTextAttribute(c_handle, 0xff0000); setCursorPosition(27, 10); printf ( "GAME ORVER!!!!!!!" ); } if ( rand () % 2 == 0) { BOX[0xff & ( r >> 4)][0xf & r] = 2; } else { BOX[0xff & ( r >> 4)][0xf & r] = 4; } Sleep(100); setCursorPosition(17 + (0xf & r) * 8 + 2 + ((0xf & r) * 2), (0xff & ( r >> 4)) * 4 + ((0xff & ( r >> 4)) + 2)); //SetConsoleTextAttribute(c_handle, BOX[0xff & ( r >> 4)][0xf & r]); printf ( "%d" , BOX[0xff & ( r >> 4)][0xf & r]); } } return 0; } |
附上另外一個(gè)小伙伴的代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
|
/* * Copyright (C) Judge Young * E-mail: [email protected] * Version: 1.0 */ #include <stdio.h> #include <time.h> /* 包含設(shè)定隨機(jī)數(shù)種子所需要的time()函數(shù) */ #include <conio.h> /* 包含Windows平臺(tái)上完成輸入字符不帶回顯和回車(chē)確認(rèn)的getch()函數(shù) */ #include <windows.h> /* 包含Windows平臺(tái)上完成設(shè)定輸出光標(biāo)位置達(dá)到清屏功能的函數(shù) */ void start_game(); /* 開(kāi)始游戲 */ void reset_game(); /* 重置游戲 */ /* 往左右上下四個(gè)方向移動(dòng) */ void move_left(); void move_right(); void move_up(); void move_down(); void refresh_show(); /* 刷新界面顯示 */ void add_rand_num(); /* 生成隨機(jī)數(shù),本程序中僅生成2或4,概率之比設(shè)為2:1 */ void check_game_over(); /* 檢測(cè)是否輸?shù)粲螒颍O(shè)定游戲結(jié)束標(biāo)志 */ int get_null_count(); /* 獲取游戲面板上空位置數(shù)量 */ int board[4][4]; /* 游戲數(shù)字面板,抽象為二維數(shù)組 */ int score; /* 游戲的分 */ int best; /* 游戲最高分 */ int if_need_add_num; /* 是否需要生成隨機(jī)數(shù)標(biāo)志,1表示需要,0表示不需要 */ int if_game_over; /* 是否游戲結(jié)束標(biāo)志,1表示游戲結(jié)束,0表示正常 */ /* main函數(shù) 函數(shù)定義 */ int main() { start_game(); } /* 開(kāi)始游戲 函數(shù)定義 */ void start_game() { reset_game(); char cmd; while (1) { cmd = getch(); /* 接收標(biāo)準(zhǔn)輸入流字符命令 */ if (if_game_over) /* 判斷是否需已經(jīng)輸?shù)粲螒?*/ { if (cmd == 'y' || cmd == 'Y' ) /* 重玩游戲 */ { reset_game(); continue ; } else if (cmd == 'n' || cmd == 'N' ) /* 退出 */ { return ; } else { continue ; } } if_need_add_num = 0; /* 先設(shè)定不默認(rèn)需要生成隨機(jī)數(shù),需要時(shí)再設(shè)定為1 */ switch (cmd) /* 命令解析,w,s,a,d字符代表上下左右命令 */ { case 'a' : case 'A' : case 75 : move_left(); break ; case 's' : case 'S' : case 80 : move_down(); break ; case 'w' : case 'W' : case 72 : move_up(); break ; case 'd' : case 'D' : case 77 : move_right(); break ; } score > best ? best = score : 1; /* 打破得分紀(jì)錄 */ if (if_need_add_num) /* 默認(rèn)為需要生成隨機(jī)數(shù)時(shí)也同時(shí)需要刷新顯示,反之亦然 */ { add_rand_num(); refresh_show(); } } } /* 重置游戲 函數(shù)定義 */ void reset_game() { score = 0; if_need_add_num = 1; if_game_over = 0; /* 了解到游戲初始化時(shí)出現(xiàn)的兩個(gè)數(shù)一定會(huì)有個(gè)2,所以先隨機(jī)生成一個(gè)2,其他均為0 */ int n = rand () % 16; for ( int i = 0; i < 4; i++) { for ( int j = 0; j < 4; j++) { board[i][j] = (n-- == 0 ? 2 : 0); } } /* 前面已經(jīng)生成了一個(gè)2,這里再生成一個(gè)隨機(jī)的2或者4,且設(shè)定生成2的概率是4的兩倍 */ add_rand_num(); /* 在這里刷新界面并顯示的時(shí)候,界面上已經(jīng)默認(rèn)出現(xiàn)了兩個(gè)數(shù)字,其他的都為空(值為0) */ system ( "cls" ); refresh_show(); } /* 生成隨機(jī)數(shù) 函數(shù)定義 */ void add_rand_num() { srand ( time (0)); int n = rand () % get_null_count(); /* 確定在何處空位置生成隨機(jī)數(shù) */ for ( int i = 0; i < 4; i++) { for ( int j = 0; j < 4; j++) { if (board[i][j] == 0 && n-- == 0) /* 定位待生成的位置 */ { board[i][j] = ( rand () % 3 ? 2 : 4); /* 確定生成何值,設(shè)定生成2的概率是4的概率的兩倍 */ return ; } } } } /* 獲取空位置數(shù)量 函數(shù)定義 */ int get_null_count() { int n = 0; for ( int i = 0; i < 4; i++) { for ( int j = 0; j < 4; j++) { board[i][j] == 0 ? n++ : 1; } } return n; } /* 檢查游戲是否結(jié)束 函數(shù)定義 */ void check_game_over() { for ( int i = 0; i < 4; i++) { for ( int j = 0; j < 3; j++) { /* 橫向和縱向比較挨著的兩個(gè)元素是否相等,若有相等則游戲不結(jié)束 */ if (board[i][j] == board[i][j+1] || board[j][i] == board[j+1][i]) { if_game_over = 0; return ; } } } if_game_over = 1; } /* * 如下四個(gè)函數(shù),實(shí)現(xiàn)上下左右移動(dòng)時(shí)數(shù)字面板的變化算法 * 左和右移動(dòng)的本質(zhì)一樣,區(qū)別僅僅是列項(xiàng)的遍歷方向相反 * 上和下移動(dòng)的本質(zhì)一樣,區(qū)別僅僅是行項(xiàng)的遍歷方向相反 * 左和上移動(dòng)的本質(zhì)也一樣,區(qū)別僅僅是遍歷時(shí)行和列互換 */ /* 左移 函數(shù)定義 */ void move_left() { /* 變量i用來(lái)遍歷行項(xiàng)的下標(biāo),并且在移動(dòng)時(shí)所有行相互獨(dú)立,互不影響 */ for ( int i = 0; i < 4; i++) { /* 變量j為列下標(biāo),變量k為待比較(合并)項(xiàng)的下標(biāo),循環(huán)進(jìn)入時(shí)k<j */ for ( int j = 1, k = 0; j < 4; j++) { if (board[i][j] > 0) /* 找出k后面第一個(gè)不為空的項(xiàng),下標(biāo)為j,之后分三種情況 */ { if (board[i][k] == board[i][j]) /* 情況1:k項(xiàng)和j項(xiàng)相等,此時(shí)合并方塊并計(jì)分 */ { score += board[i][k++] <<= 1; board[i][j] = 0; if_need_add_num = 1; /* 需要生成隨機(jī)數(shù)和刷新界面 */ } else if (board[i][k] == 0) /* 情況2:k項(xiàng)為空,則把j項(xiàng)賦值給k項(xiàng),相當(dāng)于j方塊移動(dòng)到k方塊 */ { board[i][k] = board[i][j]; board[i][j] = 0; if_need_add_num = 1; } else /* 情況3:k項(xiàng)不為空,且和j項(xiàng)不相等,此時(shí)把j項(xiàng)賦值給k+1項(xiàng),相當(dāng)于移動(dòng)到k+1的位置 */ { board[i][++k] = board[i][j]; if (j != k) /* 判斷j項(xiàng)和k項(xiàng)是否原先就挨在一起,若不是則把j項(xiàng)賦值為空(值為0) */ { board[i][j] = 0; if_need_add_num = 1; } } } } } } /* 右移 函數(shù)定義 */ void move_right() { /* 仿照左移操作,區(qū)別僅僅是j和k都反向遍歷 */ for ( int i = 0; i < 4; i++) { for ( int j = 2, k = 3; j >= 0; j--) { if (board[i][j] > 0) { if (board[i][k] == board[i][j]) { score += board[i][k--] <<= 1; board[i][j] = 0; if_need_add_num = 1; } else if (board[i][k] == 0) { board[i][k] = board[i][j]; board[i][j] = 0; if_need_add_num = 1; } else { board[i][--k] = board[i][j]; if (j != k) { board[i][j] = 0; if_need_add_num = 1; } } } } } } /* 上移 函數(shù)定義 */ void move_up() { /* 仿照左移操作,區(qū)別僅僅是行列互換后遍歷 */ for ( int i = 0; i < 4; i++) { for ( int j = 1, k = 0; j < 4; j++) { if (board[j][i] > 0) { if (board[k][i] == board[j][i]) { score += board[k++][i] <<= 1; board[j][i] = 0; if_need_add_num = 1; } else if (board[k][i] == 0) { board[k][i] = board[j][i]; board[j][i] = 0; if_need_add_num = 1; } else { board[++k][i] = board[j][i]; if (j != k) { board[j][i] = 0; if_need_add_num = 1; } } } } } } /* 下移 函數(shù)定義 */ void move_down() { /* 仿照左移操作,區(qū)別僅僅是行列互換后遍歷,且j和k都反向遍歷 */ for ( int i = 0; i < 4; i++) { for ( int j = 2, k = 3; j >= 0; j--) { if (board[j][i] > 0) { if (board[k][i] == board[j][i]) { score += board[k--][i] <<= 1; board[j][i] = 0; if_need_add_num = 1; } else if (board[k][i] == 0) { board[k][i] = board[j][i]; board[j][i] = 0; if_need_add_num = 1; } else { board[--k][i] = board[j][i]; if (j != k) { board[j][i] = 0; if_need_add_num = 1; } } } } } } /* 刷新界面 函數(shù)定義 */ void refresh_show() { /* 重設(shè)光標(biāo)輸出位置方式清屏可以減少閃爍,system("cls")為備用清屏命令,均為Windows平臺(tái)相關(guān)*/ COORD pos = {0, 0}; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); printf ( "\n\n\n\n" ); printf ( " GAME: 2048 SCORE: %06d BEST: %06d\n" , score, best); printf ( " --------------------------------------------------\n\n" ); /* 繪制表格和數(shù)字 */ printf ( " ┌──┬──┬──┬──┐\n" ); for ( int i = 0; i < 4; i++) { printf ( " │" ); for ( int j = 0; j < 4; j++) { if (board[i][j] != 0) { if (board[i][j] < 10) { printf ( " %d │" , board[i][j]); } else if (board[i][j] < 100) { printf ( " %d │" , board[i][j]); } else if (board[i][j] < 1000) { printf ( " %d│" , board[i][j]); } else if (board[i][j] < 10000) { printf ( "%4d│" , board[i][j]); } else { int n = board[i][j]; for ( int k = 1; k < 20; k++) { n >>= 1; if (n == 1) { printf ( "2^%02d│" , k); /* 超過(guò)四位的數(shù)字用2的冪形式表示,如2^13形式 */ break ; } } } } else printf ( " │" ); } if (i < 3) { printf ( "\n ├──┼──┼──┼──┤\n" ); } else { printf ( "\n └──┴──┴──┴──┘\n" ); } } printf ( "\n" ); printf ( " --------------------------------------------------\n" ); printf ( " W↑ A← →D ↓S" ); if (get_null_count() == 0) { check_game_over(); if (if_game_over) /* 判斷是否輸?shù)粲螒?*/ { printf ( "\r GAME OVER! TRY THE GAME AGAIN? [Y/N]" ); } } } |
以上所述就是本文的全部?jī)?nèi)容了,希望大家能夠喜歡。