944,103 Members | Top Members by Rank

Ad:
  • C Discussion Thread
  • Unsolved
  • Views: 572
  • C RSS
Oct 8th, 2009
0

2d-board algorithm: Total number of different moves to reach a location

Expand Post »
Hello all,

I'm trying to make a program in C, but it's actually the algorithm that's giving me hell.

The goal is to create a program that calculates and displays the total number of end-locations (all locations, including similar ones) an object can reach in a 2d board (grid), using a defined maximum of moves, using only pre-defined movements.

For example, if the object would start at (0,0), and the movements would be defined as:

movement1: (x+3) (y+1)
movement 2: (x+2) (y+3)

and the maximum of allowed moves would be 8. Then what would all the possible end-location coordinates be? (of the in total (2*2*2*2*2*2 = 64 moves?).

It's probably very easy, but i've been going crazy over it for a couple of hours now - and i keep on ending up with nested for-loops that just don't work out.

If anyone out here could give me a push into the right direction, it would be very much appreciated!
Last edited by macdonald12; Oct 8th, 2009 at 3:29 pm.
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
macdonald12 is offline Offline
9 posts
since Sep 2009
Oct 8th, 2009
0
Re: 2d-board algorithm: Total number of different moves to reach a location
If speed is not critical use a recursive function.

  1. GenNextMove(int depth)
  2. {
  3. if(depth == nMaxMove)
  4. {
  5. nTotalPos++;
  6. return;
  7. }
  8. for(i = 0;i<nMoves;i++)
  9. {
  10. GenNextMove(depth+1);
  11. }
  12.  
  13. }
  14.  
  15. main(...)
  16. {
  17. GenNextMove(0);
  18. }

You can pass the current position as well to store in a final positions array when MaxMoves is reached.
SVR
Reputation Points: 10
Solved Threads: 4
Light Poster
SVR is offline Offline
44 posts
since May 2008
Oct 8th, 2009
0
Re: 2d-board algorithm: Total number of different moves to reach a location
Thank you very much for your input SVR, i've used it to create the following code for me to practice and understand:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int x, y = 0;
  5.  
  6. int endLocations = 0;
  7. int maxJumps = 8;
  8.  
  9. void nextJump(int depth) {
  10.  
  11. if(depth == maxJumps) {
  12. printf("Endposition (x,y) = (%d,%d)\n", x, y);
  13. endLocations++;
  14. return;
  15. }
  16.  
  17. int i;
  18.  
  19. for(i=1;i<3; i++) {
  20.  
  21. switch(i) {
  22.  
  23. case 1:
  24. x = x+3;
  25. y = y+1;
  26. case 2:
  27. x = x+2;
  28. y = y+3;
  29. }
  30. nextJump(depth+1);
  31. }
  32. }
  33.  
  34. int main (int argc, char *argv[]) {
  35.  
  36. nextJump(1);
  37. printf("Total endlocations: %d\n", endLocations);
  38.  
  39. return 0;
  40. }

Considering it's getting late and i probably need some sleep, i'm most likely doing something stupid now - as this keeps on returning 128 endlocations which don't look correct.

Any further help would be much appreciated, thanks alot for your input already
Last edited by macdonald12; Oct 8th, 2009 at 6:07 pm.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
macdonald12 is offline Offline
9 posts
since Sep 2009
Oct 8th, 2009
0
Re: 2d-board algorithm: Total number of different moves to reach a location
You'll want to keep your x & y local so each move is incremented from the correct position (you'll need to pass these in as params with the starting position sent in the first call). As it is the global position is getting added to (which is the last end position you happen to be on). The local version gets restored as you return to the previous depth and things can continue from there.

As for the depth, you are starting at 1. You should start at 0. 0 position being the start and not a move).
For each path down to MaxMove you will get positions as such ...

0: x = ?, y = ? // start pos
1: x = ?, y = ? // after move 1
2: ...
...
maxJumps: x = endx, y = endy // after maxJumps

Put a printf before the maxJumps check.

With 2 options and 8 depth I think it should give you 2^8 or 256 end positions.
SVR
Reputation Points: 10
Solved Threads: 4
Light Poster
SVR is offline Offline
44 posts
since May 2008
Oct 13th, 2009
0
Re: 2d-board algorithm: Total number of different moves to reach a location
Thanks again for your help! With it i was able to make a program that simulates the movement of an object in an infinite 2d-board. The movements of this object correspond to the movements of a knight in a chess-game.

This is the code for the program:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int endLocations = 0;
  5. int routes = 0;
  6.  
  7. int xNew, yNew;
  8.  
  9.  
  10. void nextJump(int depth, int x, int y, int xEnd, int yEnd, int totalMovesAllowed) {
  11.  
  12. int xValue = x;
  13. int yValue = y;
  14.  
  15. if(depth == totalMovesAllowed) {
  16. if(xValue == xEnd && yValue == yEnd)
  17. routes++;
  18. endLocations++;
  19. return;
  20. }
  21.  
  22. int i;
  23.  
  24. for(i=1;i<9; i++) {
  25.  
  26. /** Represents all eight movements a Knight can make **/
  27. switch(i) {
  28.  
  29. case 1:
  30. xNew = xValue+2;
  31. yNew = yValue+1;
  32. break;
  33. case 2:
  34. xNew = xValue+2;
  35. yNew = yValue-1;
  36. break;
  37. case 3:
  38. xNew = xValue-2;
  39. yNew = yValue+1;
  40. break;
  41. case 4:
  42. xNew = xValue-2;
  43. yNew = yValue-1;
  44. break;
  45. case 5:
  46. xNew = xValue+1;
  47. yNew = yValue+2;
  48. break;
  49. case 6:
  50. xNew = xValue+1;
  51. yNew = yValue-2;
  52. break;
  53. case 7:
  54. xNew = xValue-1;
  55. yNew = yValue+2;
  56. break;
  57. case 8:
  58. xNew = xValue-1;
  59. yNew = yValue-2;
  60. break;
  61. }
  62. nextJump(depth+1, xNew, yNew, xEnd, yEnd, totalMovesAllowed);
  63. }
  64. }
  65.  
  66. int main (int argc, char *argv[]) {
  67.  
  68. int xBegin, yBegin, xEnd, yEnd, totalMovesAllowed;
  69.  
  70. printf("Check total amount of Knightjump routes\n");
  71. printf("Coordinates begin position: x y: ");
  72. scanf("%d %d", &xBegin, &yBegin);
  73. printf("Coordinates end position: x y : ");
  74. scanf("%d %d", &xEnd, &yEnd);
  75. printf("Number of allowed jumps: ");
  76. scanf("%d", &totalMovesAllowed);
  77.  
  78. /** Check 1 for increased efficiency
  79. this is a simple check, checking for the minimum distance that needs to be covered to even reach the end-spot
  80. **/
  81.  
  82. int deltaX, deltaY, movesNeededX, movesNeededY, totalMovesNeeded;
  83. deltaX = xEnd-xBegin;
  84. deltaY = yEnd-yBegin;
  85.  
  86. if(deltaX<0)
  87. deltaX = deltaX*-1;
  88. if(deltaY<0)
  89. deltaY = deltaY*-1;
  90.  
  91. movesNeededX=deltaX/2;
  92. movesNeededY=deltaY/2;
  93.  
  94. if(movesNeededX<1)
  95. movesNeededX=1;
  96. if(movesNeededY<1)
  97. movesNeededY=1;
  98.  
  99. if(movesNeededX >= movesNeededY)
  100. totalMovesNeeded = movesNeededX+1;
  101. else
  102. totalMovesNeeded = movesNeededY+1;
  103.  
  104. if(totalMovesAllowed >= totalMovesNeeded)
  105. {
  106.  
  107. /** Check 2 for increased efficiency
  108. This check checks for the fact that a knight-move, on a black/white-square colored board
  109. will always move from black -> white or vice-versa.**/
  110.  
  111. int beginSquare, endSquare;
  112.  
  113. if((xBegin+yBegin)%2 != 0)
  114. beginSquare = 0;
  115. else
  116. beginSquare = 1;
  117. if((xEnd+yEnd)%2 != 0)
  118. endSquare = 0;
  119. else
  120. endSquare = 1;
  121.  
  122. int difference = totalMovesAllowed%2;
  123.  
  124. if(beginSquare == endSquare && difference == 0) {
  125. /** Checks passed - Call actual function **/
  126. nextJump(0,xBegin,yBegin, xEnd, yEnd, totalMovesAllowed);
  127. } else if(beginSquare == endSquare && difference != 0) {
  128. /* not possible -> do nothing */
  129. } else if(beginSquare != endSquare && difference == 0) {
  130. /*not possible -> do nothing */
  131. } else if(beginSquare != endSquare && difference != 0) {
  132. /** Checks passed - Call actual function **/
  133. nextJump(0,xBegin,yBegin, xEnd, yEnd, totalMovesAllowed);
  134. }
  135. }
  136. printf("\nTotal amount of routes: %d\n", routes);
  137.  
  138. return 0;
  139. }


Resulting in the following output with the given input:


However, i'm supposed to be making this program more efficient - so it can calculate upfront if a given end-position can be reached from the begin-position in the given amount of moves, so that it doesn't need to calculate all routes just to come to that conclusion.

For this i added 2 checks, i think the 2nd check is fairly simple and implemented correct, however, i'm not so sure on the first check.

If anyone can give some input regarding this it would be much appreciated. And thanks again, SVR!
Reputation Points: 10
Solved Threads: 0
Newbie Poster
macdonald12 is offline Offline
9 posts
since Sep 2009
Oct 14th, 2009
0
Re: 2d-board algorithm: Total number of different moves to reach a location
i'm supposed to be making this program more efficient - so it can calculate upfront if a given end-position can be reached from the begin-position in the given amount of moves, so that it doesn't need to calculate all routes just to come to that conclusion.
That is a typical search problem. The given solution is a 'depth first' search where you search down the chain of moves before considering other moves. Potentially more efficient is a 'breadth first' search where you look at all moves at a given depth before proceeding down the chain.
Each has it's merit for a given task.

Most chess programs use a combination algorithm. Do a web search for 'A* search' and 'iterative deepening'.

Some of the logic can get pretty hairy so enjoy

As far as the current code, you should check the xEnd & yEnd before the depth. Otherwise you're only going to get routes that are maxMoves long. It may take less than that.

I dont see anything glaringly wrong with your check#1. It makes sense that the knight can move a max of 2 in any move so anything farther than movesallowed*2 can't be reached.
I bet if you think on it hard enough you can expand that logic to determine exactly how many moves it will take without having to search at all.
Last edited by SVR; Oct 14th, 2009 at 10:49 am.
SVR
Reputation Points: 10
Solved Threads: 4
Light Poster
SVR is offline Offline
44 posts
since May 2008

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C Forum Timeline: split string into 60 byte strings
Next Thread in C Forum Timeline: why use of size 0 or 1 array in structure for URI'S etc





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC