MFC implementation 2048 game (II)

Source: Internet
Author: User

On an article, the main introduction of the UI part, in fact, there is no UI, do the game itself is to realize the logic function, in fact, the logic of the game is the most difficult, the UI who can learn, logic is need to understand!

The main logic:

Two-dimensional arrays and two-terminal queues (deque) are selected, because the double-ended queue (queues) can operate the [] subscript, which is convenient to use:

int Temparray[count][count];

memcpy (temparray,m_narray,sizeof (int) *count*count);

Deque<int> lst[count];//declares an array of type deque<int> with a length of 4, which is 4 deque<int>

First the interface is initialized:

Reset, restart interface initialize void Cmy2048dlg::reset (void) {for (int i = 0; i < count; i++) {for (int j = 0; J < Count; J + +) {M_narray[i ][J] = 0;}} Randonnum (); Randonnum ();}

This is nothing, randnum () is a random number generation function.

TodownwardAs an example: we want to group two-dimensional arrays with a double-ended queue array LST:
The original array00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33
After groupingFirst queue: lst[0]: 00 10 20 30
Second queue: lst[1]: 01 11 21 31
Third queue: lst[2]: 02 21 22 32
Fourth queue: Lst[3]:

So after grouping:
lst[0][0] = temparray[0][0];
LST[0][1] = temparray[1][0];
LST[0][2] = temparray[2][0];

The above analysis is only a case of relative assumptions, not in fact because the grouping has a condition: m_narray[i][j]! = 0
So it's just going to group data that's not 0.


Now analyze a situation: the first column of the original array is 4
2
0
0
Then after the group in fact Lst[0] as long as two data: Lst[0][0]: 4; Lst[0][1]:2;

We look at the code implementation of the grouping:

int temparray[count][count];memcpy (temparray,m_narray,sizeof (int) *count*count);d eque<int> lst[Count];// Declares an array of type deque<int> of length 4, which is 4 deque<int>for (int i = 0; i < count; i++) {for (int j = 0; J < Count; J + + {if (m_narray[i][j]! = 0) {Lst[j].push_front (m_narray[i][j]);}}}

So after grouping: lst[0] As long as two data: Lst[0][0]: 4; Lst[0][1]:2;

The original array is 4 2 0 0, then we press the down button it should change to 0 0 4 2:

Between this we have to deal with the data in the LST and reverse the processing:

Implement cumulative void Cmy2048dlg::add (deque<int> &list) {for (int i = 0; i < list.size (); i++) {if (list[i] = = 0) continue; for (int j = i+1; J < List.size (); j + +) {if (list[i] = = List[j]) {list[i] *= 2;list[j]  = 0;break;} If the current value is not 0 out of the  inner loop, there is no need to compare it for example:  4 2 2; when list[0]=4,list[1]=2//list[1] = 2! = 0, jump directly out of the loop, no need to compare list[2] with list[0]if (LIS T[J]! = 0) {break;}}} Rearrange the order, 0;//for example 4 2  after the above code actually does not have any changes in the accumulation, but the cumulative final result to become  4 2 0 0  deque<int> templst;for (int i = 0; i < List.size (); i++) {//double-ended queue supports subscript access to an element if (list[i]! = 0) {templst.push_back (list[i]);}} list = Templst; This time the list element is: 4 2, so the following to fill 0for (int i = list.size (); i < Count; i++) {list.push_back (0);//list element is: 4 2 0 0}}
Invert data void Cmy2048dlg::reservedlst (deque<int> &lst) {deque<int> templst;while (lst.size ()! = 0) { Templst.push_back (Lst.back ()); Lst.pop_back ();} LST = Templst; The list element after reversal is 0 0 2 4}


Then look at the downward code:

BOOL Cmy2048dlg::D Own (void) {int temparray[count][count];memcpy (temparray,m_narray,sizeof (int) *count*count);d Eque <int> lst[count];//declares an array of type deque<int> of length 4, which is 4 deque<int>for (int i = 0; i < Count; i++) {for T j = 0; J < Count; J + +) {if (m_narray[i][j]! = 0) {Lst[j].push_front (m_narray[i][j]);}}} accumulate for (int i = 0; i < Count; i++) {Add (lst[i]);//This assumes for lst[0]; add: lst[0][0]: 4; lst[0][1]:2; no change in this case//because it is added with LS T[0][0], lst[1][0] as the benchmark, so here to add down, you need to reverse the reservedlst (Lst[i]);} Re-assignment for (int i = 0; i < count; i++) {for (int j = 0; J < Count; J + +) {M_narray[i][j] = lst[j][i];//Note this is lst[j][i] Assignment to m_narray[i][j]}}//detection change for (int i = 0; i < count; i++) {for (int j = 0; J < Count; J + +) {if (m_narray[i][j]! = Temp Array[i][j]) {return true;}}} return false;}


This process is illustrated with an example:

For example, now the first column is 2.

2

0

0

Then it is grouped lst[0]: There are two data: Lst[0][0] is 2 lst[0][1] 2

ADD (Lst[0]); After add LST becomes 4 0, then 4 0 0 0

Reservedlst (Lst[i]); After Reservedlst, LST becomes 0 0 0 4;

To achieve our results!

Up, left, and right the code is basically the same:

There are two places to be aware of:

When you group down and to the right, the front-end insert queue:

for (int i = 0, i < count; i++) {for (int j = 0; J < Count; J + +) {if (m_narray[i][j]! = 0) {Lst[j].push_front (m_narray[ I][J]);}}}

When you group up and to the left, the back end inserts the queue:

for (int i = 0, i < count; i++) {for (int j = 0; J < Count; J + +) {if (m_narray[i][j]! = 0) {lst[i].push_back (m_narray[i ][J]);}}}

As for why the two are not the same, mainly because of reversing the reason there!

The last is the logic of the end,
As long as 22 are not the same, the game is over:

Logic to deal with the end of the game: bool Cmy2048dlg::calcend (void) {//handles the horizontal axis first: for (int i = 0; i < count; i++) {for (int j = 0; J < Count; J + +) { if (m_narray[i][j] = = 0) {return false;} if (j+1 = = Count) {break;} if (m_narray[i][j] = = M_narray[i][j+1]) {return false;}}} Handle the longitudinal axis for (int i = 0; i < count; i++) {for (int j = 0; J < Count; J + +) {if (m_narray[i][j] = = 0) {return false;} if (i+1 = = Count) {break;} if (m_narray[i][j] = = M_narray[i+1][j]) {return false;}}} return true;}


Game panel design: is to divide a customer division into 16 small pieces, not a small block corresponding to the number of elements of each array display:

else//Initialize the game face disk {CRect rect; GetClientRect (rect);//Gets the coordinates of the client area of the window are relative to the upper-left corner of the window client area, so the upper-left corner coordinates are (0,0). Rect.left + = 5;rect.right = 5;rect.top + 5;rect.bottom-= 5; CPAINTDC DC (this); int nwidth = rect. Width ()/count; The width of each cell is int nheight = rect. Height ()/count;//cfont Font;font for each cell. CreatePointFont (Nheight*5, _t ("Arial"), &AMP;DC); Create font and size cfont* Oldfont = DC. SelectObject (&font);//Save the old font DC. SetBkMode (TRANSPARENT);//Set the background color to transparent for (int i = 0; i < count; i++) {for (int j = 0; J < Count; J + +) {CRect Rectchild;rec Tchild.left = rect.left + j*nwidth;rectchild.top = rect.top + i*nheight;rectchild.right = rectChild.left + nWidth;r Ectchild.bottom = Rectchild.top + NHEIGHT;DC. Draw3drect (Rectchild,rgb (255,0,0), RGB (255,0,0)), if (m_narray[i][j]! = 0) {CString strtext;strtext.format (_t ("%d"), M _NARRAY[I][J]);//The function is to write formatted text in the specified rectangle, format the text according to the specified method//(Extended tab, character alignment, fold line, etc.) DC. DrawText (strtext,rectchild,dt_center| Dt_vcenter);}}} Cdialogex::onpaint ();d c. SelectObject (Oldfont);//select Back to the original font. Deleteobject ();//Delete font} 


The keyboard message is then processed, and the interception of the keyboard message is overloaded with the PreTranslateMessage () function:

Intercept the keyboard message bool Cmy2048dlg::P retranslatemessage (msg* pMsg) {bool BRet = false;if (pmsg->message = = Wm_keydown) { Switch (pmsg->wparam) {Case vk_down:bret = down (), break;case Vk_up:bret = Up (), break;case Vk_left:bret = left (); Case Vk_right:bret = right (); break;default:break;} if (Calcend ()) {AfxMessageBox (_t ("gameover!")); Reset ();} Else{if (BRet) {randonnum (); Invalidate (TRUE); if (Calcend ()) {AfxMessageBox (_t ("gameover!")); Reset ();}}} Invalidate (TRUE);} return CDialogEx::P retranslatemessage (PMSG);}


The feeling with the text explanation or is really more difficult, is for oneself combed the next thought:

Source: Click to open the link; Big god do not look, write bad; Novice can look together to learn! Text interpretation is more difficult to explain, or to see the code slowly understand!




MFC implementation 2048 game (II)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.