To the news: Push box game automatic solution algorithm design (IV.)

Source: Internet
Author: User

This section is the core of this paper, that is, the process of design thinking of solving algorithm of pushing box game


As has been said before, the best criterion for judging the situation is not the exact same situation, but the same coordinates and the role coordinates.

For example, no matter how the character moves, does not push the box, can return to the original position, counted as the same situation:

Again, two boxes interchange position, the result and no moving box is the same, so the sorting box coordinates after the same, or the same situation


Q: Is it necessary to judge the situation to be repeated? Is it just a boost to efficiency?

A: Not to improve efficiency, but to be able to solve it, if recursive, repeat the situation repeatedly exhausted the stack, and the queue runs out of memory

Just like, push the two boxes back and forth repeatedly.


Q: Sorting all the boxes to compare, too chicken, there is no essence?

A: Yes, that is the hash table, but the hash table has a hint of the risk, that is, if the calculation results hash difference, then the two groups of cotton data must be different

But if the result is the same, the two groups of cotton data may also be different, of course, the same data length different data hash the same probability is extremely low, like MD5 the number

According to the length of the hash, the repetition is lower, the Earth's sand will be hashed again may be a few repetitions, in order to speed, I use CRC32


Q: So, with the base above, move the movers in four directions to generate a snapshot, and then recursively go down?

A: Theoretically yes, but as mentioned above, the porter does not push the box when it makes no sense, belongs to the idle walk, our object should be transferred to the box

, and not the porter. Push each box in four directions to create a snapshot, filter duplicates, and "recursively" until all the boxes are returned.


To sum up, we can start the work, give a small problem to think, get the solution, there will be a better solution? Or a different question: How is the queue handled?

My plan is: first- in first-out , that is, first to join the queue first processing, so that the lower steps to ensure a snapshot, first analyzed, the lower step is of course a better solution, and finally the first

The solution is naturally the best solution ...


Scenario Data structure:

#pragma pack (4)//STAR. Value (__int64) defaults to 64-bit aligned typedef struct TAGSTAGE{UINT volume;//struct actual size (accelerated calculation) UINT flags;//scene identification Pstar stars;//box position list (internal pointer , not released, quantity is. Count) Pstar series;//Sort box coordinates (internal pointer, not released, quantity is. count) UINT count;//Box Qty (target number) UINT value;//number of uint hash;//scene fingerprint (box coordinate sort hash value) Tagstage *prev;//last Scene (in-game connection queue operation, pseudo pointer, not released) Tagstage *next;//Next Scene (in-game connection queue operation, pseudo pointer, not released) Tagstage *host;//parent scene (when solving a reverse parent search gets the solution path, pseudo-pointer, not released) union {STAR size;//scene size Struc t {long sizex;//scene width (number of columns) long sizey;//scene height (number of rows)};}; Union {STAR position;//role current position struct {Long posx;//role horizontal position long posy;//character vertical position}; Union {STAR automation;//auto pathfinding location struct {Long autox;//pathfinding horizontal coordinate long autoy;//pathfinding vertical coordinates}; Pmove moves;//feasible walk-through list (internal pointer, not released, quantity is. Count * 4: Four directions) UINT range;//feasible way quantity uint index;//current test walk-in UINT slaves;//remaining non-parsed sub-scene number UINT layer;//current steps Union {BYTE matrix[1]; Matrix data Long data;};} STAGE, *pstage; #pragma pack ()

The internal pointer points to the inside of the structure, such as stars pointing to the coordinates of each box, instead of converting the matrix to calculate the offset, we use 32 bits of memory in exchange for more than 20 assembly instructions

An assassin for a dynasty,,, a good quick sword ...


Star is the data structure of the AlphaStar algorithm and is a coordinate pair

typedef Union tagstar{//Point Type (8B) struct {long x;long Y;}; __int64 Value;} STAR, *pstar;

Move is a way of moving information, recording the impact of some kind of data, accounting for 48 bytes, also stored in the structure of the inside, confined to the length here is not detailed


Then the queue data structure:

typedef struct TAGQUEUE{//is different from stack, first-out UINT volume;//queue Capacity (bytes) uint size;//element memory size UINT count;//element Upper index UINT value;//current element number ( Next index) UINT used;//number of elements uint step;//result steps pstage active;//first active scene (from this popup) Pstage backup;//end of active scene (to this press) Pstage stages;//expired Scene (Press-in eject) Pshot shots;//failed Snapshot list (external pointer, external release) Pstack stacks;//scan coordinate list (external pointer, external release) union {BYTE Dummy[1]; UINT Data;};} QUEUE, *pqueue;

The logical process of the solution is as follows:

1. Initialize the queue, extract the first scene to the current scene

2. The current scene all boxes are returned, function return

3. Analyze the scene to get a number of new scenes, filter duplicate

4. Filter new scene number is zero, scene no solution, delete scene (can be optimized, see next article)

5. Append a new scene to the queue, analyze the next scene in the queue, repeat 2-4

6. The number of queue scenes is zero, the scene is no solution (or the queue is too small, memory is low)


The function code for generating a new scene based on the previous level scenario (see the resource bundle for additional code, which is limited in length, not detailed here):

Request a scene from the queue and populate it with the current scene, detect duplicates after scanning, and append to queue Pstage fnstagenext (pqueue pqueue, pstage pstage, int *pdwcode) {pstage pnext;// Into the next scenario pmove pmove;int dwret;pnext = fnqueueapply (Pqueue), if (Pnext = = NULL) {if (pdwcode) *pdwcode = 0;//Queue exhausted Fnstagecode ( Sec_cache_null); return NULL;} Copy ancestor data, fix pointer v32copy (Pnext, Pstage, pstage->volume);p next->host = pstage;//. Prev and. Next are assigned a value fnstageptr (Pnext) before discarding or when joining a queue;//correcting internal pointers//pushing the scene pmove = &pstage->moves[pstage->index];# According to the current action Ifdef _debug//fnprint ("Current scene =0x%08x, parent scene =0x%08x, player = (%d,%d), box: \ r \ n", Pstage, Pstage->host, PSTAGE->POSX, Pstage->posy);//fnprintbox (pstage);//fnprint ("Current Action: Box%d moved to (%d,%d), player moved to (%d,%d), seek coordinates (%d,%d)." \r\n\r\n ",// Pmove->index, PMOVE->OBJX, Pmove->objy, Pmove->portx, Pmove->porty, Pmove->movex, PMove->MoveY) ; #endiffnStagePush (Pnext, Pmove, smf_move_none);//Application Go Pnext->range = 0;//no go pnext->index = 0;//...pnext-> layer++;//number of steps//scan line fill the accessible unit if (pnext->posx = = 2 && pnext->posY = = 4) {dwret = 0;} Dwret = Fnstagescan (Pqueue, pnext);//test situation repeat Pnext->hash = Fnstagehash (Pnext->stars, Pnext->series, pNext-> count);//Sort computed Hash Dwret = Fnstageloop (Pqueue, Pnext), if (dwret! = 0) {#ifdef _debugfnprint ("Discard repeating scene =0x%08x.\r\n", pstage); Endifpnext->prev = null;//orphaned to prevent queue deletion (the scene has not been queued, only appended to the Recycle list) Pnext->next = Null;fnqueueremove (Pqueue, pnext);// Remove scene if (pdwcode) *pdwcode = -1;//repeat situation fnstagecode (sec_error_none);//Clear 0 error return NULL;} The function returns if (pdwcode) *pdwcode = 1;return Pnext;}

Operating effect:

Debug Log file contents (in the next section, further optimization of the program, this result has not been optimized):

Start solving, Queue size = 8192, solution size =200 ... solve successfully, queue use peak = 3869, remaining valid number =3867! (4, 1) <4, 2> (3, 5) <3, 4> (2, 4) <2, 3> (5, 4) <4, 4> (4, 2) <4, 3><3, 3><3, 4> (1, 3) &L T;2, 3><3, 3><4, 3> (6, 3) <5, 3> (5, 4) <4, 4><3, 4> (3, 3) <4, 3> (1, 4) <2, 4> (5, 4) <5, 3> (2, 4) <3, 4> (2, 1) <2, 2><2, 3> (3, 6) <3, 5><3, 4><4, 4> (1, 4) <2, 4> <3, 4> (6, 2) <5, 2> (4, 3) <3, 3> (5, 5) <5, 4> (3, 4) <4, 4> (1, 3) <2, 3> (4, 1) <4, 2>&L T;4, 3><3, 3> (2, 4) <2, 3> (6, 3) <5, 3><4, 3><3, 3> (5, 5) <5, 4> (3, 4) <4, 4> (6, 3) <5, 3><5, 4> (3, 3) <4, 3> (1, 3) <2, 3> (2, 1) <2, 2> best solution pushed 43 times, pathfinding 29 times, total coordinates 72!


To the news: Push box game automatic solution algorithm design (IV.)

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.