一. 前言3 X4 Z+ H" \: e+ q4 G" }
在我们的DIY套件上,终于集成了第三个小游戏----2048。怎么感觉做成了个游戏机呢(#.#)。/ Y% k9 ?9 h/ G3 G! ?
这款游戏也是非常流行的,玩起来也是非常的轻松,要想过关的话,还是需要一点的技巧。
. M( T% J( \. Z; y' N$ X( ?; N
, o. n# i4 a$ G; }/ ]1 o+ K二. 游戏规则简介- G) d' k, s7 Z/ {1 I' n
1.游戏地图为 4 * 4。
# e4 v* y }) `2 S. w8 `( [7 c2.每次移动所以方块都会向指定的方向移动,同时会在地图上随机生成值为2或者4的方块。
# {4 V. @6 D7 o5 x$ ~) H3.在移动的过程中,如果相邻的两个方块的值一样,那么它们就会融合成一个值为它们之合的方块,每一次移动,只能进行一次融合。$ }9 \5 I" B2 |9 m! i8 G% ^$ w9 c
4.如果方块中的值为2048,则游戏胜利。如果整个地图都被方块添满了,则游戏失败。
! y( S5 a+ Q# }( R" R三. 核心代码介绍" B5 Z4 M3 j0 L: V1 I9 G
方块的随机生成,和胜利的判断的实现都较为容易。整个游戏的核心部分为第三点,方块的移动和融合,这个部分如果弄懂了的话,整个游戏实现起来会非常容易。1 X+ A/ ^( m) @) _& f
先在Visual Studio实现这一过程的准确性,然后在搬运到keil中去,这一方便debug发现问题。
& x6 x" r" ~9 f& S5 W
# c. M& c' f) f% n8 |这里先合并,后移动
7 t+ ^6 b M; [7 S/ i6 C% j# }2 d
" `7 s) `4 C0 E1.通过定义一个长度为4的数组,来模拟一行数据。
# \5 y4 D1 n" m$ g: S7 A3 v- int Map[4] = { 0,8,0,8 };
复制代码 ! W. I8 m8 D- s, G* s/ [
2.通过循环来找到可以合并的两个数,将其合并
5 d+ x; n) c- q) P9 @$ O- for (j = i + 1; j < 4; j++)
, o& U4 n6 Y6 \5 @" Q - {
) ]8 y7 p! a& N( [- M2 V - //如果不为0,且当前选择的值也不为0,且和这个数不相等,则跳过! P. l( V9 A, t% z* n: b x$ k
- if (Map[j] != Map&& Map[j] != 0): h9 H9 S3 p& b3 ]" V" D0 }# E& _+ w
- break;& u. n4 e8 Z7 P* v6 I
, X& B* I1 e+ I! Q- //如果有相等的两个方块,且中没有其余方块,进行融合- K1 [0 d7 ?. ^0 u% P' C$ @+ U( M
- if (Map[j] == Map)5 o" p6 ?- B/ w/ @
- {1 _, B2 a* n5 c; D
- Map[j] = 0; //先将这方块消除掉
8 E+ j4 Y$ C5 h! c: j$ z - unsigned char k;
& }) d. o$ d0 I! C# D2 V( X% I - for (k = i + 1; k < 3; k++)5 I7 w5 J; x$ Y: m+ i8 l6 ]2 O
- {
4 S1 X6 M( f" C1 G3 l7 T - Map[k] = Map[k + 1]; //移动一次方块" I/ z7 O4 [! K+ j) o. B3 h
- }! u& ~1 Y4 r; I$ h0 e& @
- Map += Map;//更新融合后的方块的值
2 X, o0 o4 v6 A# n% ^1 W. M - Map[3] = 0;' E- t! F0 o. D+ }2 ?0 A2 R
- flag = 1;
Y% Y: C3 |3 w' [( f( h - break;
+ o$ f* ~8 d' A) K1 \ - }4 m; a" X% j5 [6 U5 v1 u* Y0 \4 o
- }- L7 V0 ^9 v+ n5 m% s* F
复制代码 ! |( |. @' p9 ^6 R1 G# g
3.移动所有方块,直到所有方块都靠在一起$ m8 w! s3 J* h, Q' l9 _) a# }# W5 d
- while (1)" q9 t* m1 R v* A
- {7 K' Y/ b! ^/ t l, D
- int j, flag = 0;
% s4 [7 K' x3 M/ `7 { - for (i = 0; i < 3; i++)
! d. r Z: Z- {" [7 g8 ^ - {( `+ r! d7 K+ O5 B. C* @% Q
- if (Map == 0) //有空的方块,说明可以移动
C, s0 @. U+ q- R - {7 I' b7 f- h" E2 G! `. C
- Map = Map[i + 1];
" B" z& R3 F/ ]9 t - Map[i + 1] = 0;6 ^, y M. e% Q! B5 K1 R4 ~
- }
) |( N+ v0 T; A \! k* j - }2 M# o/ } `9 T( b. x
- for (j = 0; j < 3; j++): j/ {- z W" q; x# E9 {0 T7 N
- {
0 S& r8 R: u3 R) v; k. ?. U - if (Map[j] == 0)
, [8 r. ]; _) n) t, V - {
, c% o; l1 p: G: F! W - int k;
4 b, N6 k" F8 \/ s. h. a: c+ h - for (k = j + 1; k < 4; k++) U0 B3 c; m+ o: k
- {1 z! f' i6 O+ ^2 ?" y, w
- if (Map[k] != 0) //判断是否继续移动
* R" ^1 l v+ j3 I - {
! y6 k4 q+ o0 Y& L - flag = 1;
! G9 Z. J% s* v, m& A2 f - break;
V/ Y+ M7 F r - } ` T; A5 W: L$ }( s
- }
/ _- W& Q1 G9 ~9 B - }
@8 A% Q. F8 { - }" [ ~$ O F" G' y
- if (flag == 0)
' H# _: P3 e/ O: v - break;
* S5 ^6 p, I7 c - }
复制代码
2 j1 I: K- U" o4.测试结果展示
1 `+ X6 c [9 i. U
4 l2 H, g* b+ C0 _
; @$ {( @: G- R
- _6 w1 R6 k0 _0 c' u5 S
1 N2 f1 [# ?* J# i# E
2 _6 r3 E0 k7 K( j" v4 C% o
, `# g! B7 h5 g1 c W, s! a# z
3 Y# f5 V% d- H) @- n
4 ~% G# h6 f- r7 D+ D; S6 w
完整测试代码' J. A% K, q7 g1 T' b" l
9 b; G( j. u, t* i" O1 X
7 \5 O9 k, o$ e! [' q, u n- int main(void)6 B! R& ]! k5 x& R [
- {
0 Z X; f6 {9 U) S8 J, Z - int Map[4] = { 0,2,4,8};/ ~6 }/ B K" R
- int i,flag = 0;
$ r5 x: O. g, T7 ~1 e q2 V6 V - int flags = 0;
% c0 a( i; N% D* g) x+ V9 k( B4 Z - for (i = 0; i < 4; i++)
8 K9 U0 I5 U4 m7 r6 C) G$ {' M5 D - printf("%d\t", Map);+ P. Z6 K d6 ?( ~. o9 g3 C
- printf("\n");
) b# R1 W- X+ N2 E4 q2 |$ J( I - 9 w$ s5 w) ~+ K/ F+ @7 m5 |. m( S
- for (i = 0; i < 3; i++)1 Z" c) L o' p; M5 t& R1 ~
- {
- G: \: n* q8 z6 L. \ - unsigned char j;
8 M9 ]& D. d6 d. {) m1 D0 r9 L - for (j = i + 1; j < 4; j++)
4 `7 z0 |8 v7 l' x) e2 p r1 `8 y - {
* S) K) I; ~7 ? - //如果不为0,且当前选择的值也不为0,且和这个数不相等,则跳过. ]! X8 U" T8 V7 l0 R
- if (Map[j] != Map && Map[j] != 0)
% c1 p, Z; t7 b2 R3 q9 h7 U, p - break;
. i7 }6 E: [7 {% e7 j8 p" S
0 v; q r7 `, R+ P" L- {! I, ?9 t% D- //如果有相等的两个方块,且中没有其余方块. i ~. m- S, {( R0 e! c6 C. k
- if (Map[j] == Map); V) t. L1 Z# a* J$ A" \: o) K: [
- {7 f& D: b3 _1 z0 y: V6 q7 }$ v4 u" V$ P
- Map[j] = 0;
5 l0 O" `: G6 N! `( d) b, D - unsigned char k;
7 b' f, J! J, z" q& m - for (k = i + 1; k < 3; k++)
+ Q8 X: B/ o3 I - {
6 B# w2 t5 x( x) U" v5 T3 n - Map[k] = Map[k + 1];
0 k; O) j' o9 h" }- a( }; A - }
' ~2 i$ q: u% J# H9 }* X) n - Map += Map;
" T& t7 N* B" I: O9 J" z - Map[3] = 0;2 S2 u$ M; |+ m
- flags = 1;6 ], u' k* Z! X' ~ |7 t
- break;
5 n" e$ I5 I1 _! n$ k - }" e6 w7 V* V* g" x' D0 R R
- }, o% J- T: |$ ^( \* j/ J3 |$ u
- ) C `7 P1 E8 e& k5 E9 i1 H9 [
- while (1)
. W, O- ] Y+ C H - {7 L: v4 A( B; ~
- int j, flag = 0;! s/ z0 ~' T+ g/ |
- for (i = 0; i < 3; i++)6 r3 }: N% K h8 [7 N
- {
4 S* N3 c( \# x# _" d3 }; c, b% v - if (Map == 0)$ {% E' ^; x% H2 u+ `# ?
- {1 S, M* o* [4 o1 n1 y
- Map = Map[i + 1];9 E1 _# M: U/ _
- Map[i + 1] = 0;
9 _8 U& j; u/ m8 C8 r - }
, |6 Q k% u+ _9 k/ [+ @ - }* \# k- C/ P% r. w9 P: g
- for (j = 0; j < 3; j++)
5 ~% c) e7 h. y* g& V2 n/ M - {5 f% ^; Z, O3 c0 x' V1 U2 e) Z
- if (Map[j] == 0)- G8 u4 |% k7 W1 v: |
- {
8 Q4 q& W% T" [/ ^' Y4 p- g% t- M6 O - int k; u; J3 g5 g5 \4 g
- for (k = j + 1; k < 4; k++)) z. j4 X& d5 K% u V. p
- {
9 p& I: U- P& ~3 J# j - if (Map[k] != 0)
! B! U- p- \" h" o! E5 J* G: X - {
: @( m8 Q- D% n# x% E - flag = 1;
9 G, g6 t- N( z9 Y R9 ~ a - break;! s% Z3 i$ Y1 M+ u1 K3 N
- }
4 S8 S8 o Q# G# m1 n - }4 C+ Y% h2 U+ `9 q
- }1 z! H' t3 M/ Y0 [5 t1 I! z" {
- }: t2 }: R6 Y* E& l( D3 H2 v
- if (flag == 0)
' n7 u! y- R5 m - break;: U& t" m: g2 l$ L5 r- O
- }
9 v7 m, E( M$ {4 q" w - for (i = 0; i < 4; i++)
1 x1 |1 x/ {6 \) Q* @3 {4 L$ } - printf("%d\t", Map);
, K" r* }8 t A) V* `, Q) b0 j: t - printf("\n");
7 `0 r+ G2 }; j7 o, L -
- Y, U9 z. O, | - }
% M7 T' L) [# C% Y0 C - return flags;% R! K/ z: H- B6 _
- }
复制代码
1 Y4 N6 M- ^' m+ i" S V K" M6 a* h1 i5 j. S: Q' `
5 d2 i1 f: a9 {) o- k
7 K) _: [! o- K7 Z' g( x! T+ o
, k! d* C0 m( J3 Z$ a5 D" |, t7 z |