效果不好,見諒,沒事就寫了一個!!!
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; } |
附上另外一個小伙伴的代碼
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ù)種子所需要的time()函數(shù) */ #include <conio.h> /* 包含Windows平臺上完成輸入字符不帶回顯和回車確認的getch()函數(shù) */ #include <windows.h> /* 包含Windows平臺上完成設定輸出光標位置達到清屏功能的函數(shù) */ void start_game(); /* 開始游戲 */ void reset_game(); /* 重置游戲 */ /* 往左右上下四個方向移動 */ void move_left(); void move_right(); void move_up(); void move_down(); void refresh_show(); /* 刷新界面顯示 */ void add_rand_num(); /* 生成隨機數(shù),本程序中僅生成2或4,概率之比設為2:1 */ void check_game_over(); /* 檢測是否輸?shù)粲螒颍O定游戲結束標志 */ int get_null_count(); /* 獲取游戲面板上空位置數(shù)量 */ int board[4][4]; /* 游戲數(shù)字面板,抽象為二維數(shù)組 */ int score; /* 游戲的分 */ int best; /* 游戲最高分 */ int if_need_add_num; /* 是否需要生成隨機數(shù)標志,1表示需要,0表示不需要 */ int if_game_over; /* 是否游戲結束標志,1表示游戲結束,0表示正常 */ /* main函數(shù) 函數(shù)定義 */ int main() { start_game(); } /* 開始游戲 函數(shù)定義 */ void start_game() { reset_game(); char cmd; while (1) { cmd = getch(); /* 接收標準輸入流字符命令 */ 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ù),需要時再設定為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; /* 打破得分紀錄 */ if (if_need_add_num) /* 默認為需要生成隨機數(shù)時也同時需要刷新顯示,反之亦然 */ { add_rand_num(); refresh_show(); } } } /* 重置游戲 函數(shù)定義 */ void reset_game() { score = 0; if_need_add_num = 1; if_game_over = 0; /* 了解到游戲初始化時出現(xiàn)的兩個數(shù)一定會有個2,所以先隨機生成一個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)生成了一個2,這里再生成一個隨機的2或者4,且設定生成2的概率是4的兩倍 */ add_rand_num(); /* 在這里刷新界面并顯示的時候,界面上已經(jīng)默認出現(xiàn)了兩個數(shù)字,其他的都為空(值為0) */ system ( "cls" ); refresh_show(); } /* 生成隨機數(shù) 函數(shù)定義 */ void add_rand_num() { srand ( time (0)); int n = rand () % get_null_count(); /* 確定在何處空位置生成隨機數(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); /* 確定生成何值,設定生成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; } /* 檢查游戲是否結束 函數(shù)定義 */ void check_game_over() { for ( int i = 0; i < 4; i++) { for ( int j = 0; j < 3; j++) { /* 橫向和縱向比較挨著的兩個元素是否相等,若有相等則游戲不結束 */ if (board[i][j] == board[i][j+1] || board[j][i] == board[j+1][i]) { if_game_over = 0; return ; } } } if_game_over = 1; } /* * 如下四個函數(shù),實現(xiàn)上下左右移動時數(shù)字面板的變化算法 * 左和右移動的本質一樣,區(qū)別僅僅是列項的遍歷方向相反 * 上和下移動的本質一樣,區(qū)別僅僅是行項的遍歷方向相反 * 左和上移動的本質也一樣,區(qū)別僅僅是遍歷時行和列互換 */ /* 左移 函數(shù)定義 */ void move_left() { /* 變量i用來遍歷行項的下標,并且在移動時所有行相互獨立,互不影響 */ for ( int i = 0; i < 4; i++) { /* 變量j為列下標,變量k為待比較(合并)項的下標,循環(huán)進入時k<j */ for ( int j = 1, k = 0; j < 4; j++) { if (board[i][j] > 0) /* 找出k后面第一個不為空的項,下標為j,之后分三種情況 */ { if (board[i][k] == board[i][j]) /* 情況1:k項和j項相等,此時合并方塊并計分 */ { score += board[i][k++] <<= 1; board[i][j] = 0; if_need_add_num = 1; /* 需要生成隨機數(shù)和刷新界面 */ } else if (board[i][k] == 0) /* 情況2:k項為空,則把j項賦值給k項,相當于j方塊移動到k方塊 */ { board[i][k] = board[i][j]; board[i][j] = 0; if_need_add_num = 1; } else /* 情況3:k項不為空,且和j項不相等,此時把j項賦值給k+1項,相當于移動到k+1的位置 */ { board[i][++k] = board[i][j]; if (j != k) /* 判斷j項和k項是否原先就挨在一起,若不是則把j項賦值為空(值為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() { /* 重設光標輸出位置方式清屏可以減少閃爍,system("cls")為備用清屏命令,均為Windows平臺相關*/ 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); /* 超過四位的數(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]" ); } } } |
以上所述就是本文的全部內容了,希望大家能夠喜歡。