# Include <stdio. h> # include <ctype. h> # include <stdlib. h> # include <time. h> # define size 4 # define swap (X, Y, t) (t) = (x), (x) = (y), (y) = (t) int * total_choice = NULL; int step = 0; void display (INT Board [] [size]); // display the Board function int is_valid (INT Board [] [size], int choice ); // void move (INT Board [] [size], int choice) function used to determine whether a player is valid ); // function for moving numbers int is_complete (INT Board [] [size]); // void initial (INT Board [] [size]) function for determining whether the puzzle is completed; // Initialize the checker void turn_left (INT Board [] [size]); // shift the left of the Computer void turn_right (INT Board [] [size]); // shift void turn_up (INT Board [] [size]) to the right of the computer; // move void turn_down (INT Board [] [size]) on the computer; // move void main () {int Board [size] [size] ={// the Board {, 3,4}, // initial values are reference numbers {5, 6, 7,8}, // used to select a vacant square for {9, 10, 11, 12}, // a turn {13, 14, 15, 0 }}; char again = 0; int choice = 0; int I = 0; Long Now = 0; int step = 0; Printf ("Welcome to simple jigsaw puzzle \ n"); printf ("select a number, which will be moved to a space \ n "); printf ("if this number cannot be moved, it will be displayed and the player will be re-selected to move the number \ n"); printf ("good luck! Press enter to start. \ n "); scanf (" % C ", & again); total_choice = (int *) malloc (15 * sizeof (INT); initial (Board ); display (Board); getchar (); for (I = 0; I <15; I ++) {move (board, total_choice [15-i-1]); display (Board ); now = clock (); For (; clock ()-Now <clocks_per_sec;); System ("CLS") ;}do {for (;) {display (Board ); printf ("Enter the number you want to move:"); scanf ("% d", & choice); If (is_valid (board, choice )) // if the value is valid, move the number and display the result {move (board, choice); display (boar) D); System ("CLS"); // clear screen} else // if the movement is invalid, it is displayed as invalid mobile printf ("invalid mobile \ n "); if (is_complete (board) & is_valid (board, choice) {display (Board); printf ("Good job! \ N "); printf (" mission completed! \ N "); break;} printf (" do you want to play it again? (Y or N) "); scanf (" % C ", & again) ;}while (tolower (again) = 'y ');} void display (INT Board [] [size]) {int ROW = 0; // row indexint Col = 0; // column indexfor (ROW = 0; row <size; row ++) {printf ("+"); For (COL = 0; Col <size; Col ++) printf ("---- + "); printf ("\ n"); For (COL = 0; Col <size; Col ++) printf ("| % 2D % s", Board [row] [col], board [row] [col]? "": "\ B"); // displays the number on the board. When the number is 0, it is displayed as a blank printf ("| \ n ");} printf ("+"); For (COL = 0; Col <size; Col ++) printf ("---- + "); // display the bottom lineprintf ("\ n"); // display the end of bottom line} int is_valid (INT Board [] [size], int choice) {int ROW = 0; int Col = 0; int rowdelta = 0; // row increment around a squareint coldelta = 0; // column increment around a squareint flag = 0; // jump out of the loop mark for (ROW = 0; row <size; row ++) // gets the position of the number selected by the player {for (c OL = 0; Col <size; Col ++) {If (Board [row] [col] = choice) {flag = 1; break ;}} if (flag = 1) break;} For (rowdelta =-1; rowdelta <= 1; rowdelta ++) {for (coldelta =-1; coldelta <= 1; coldelta ++) {// The out-of-boundary location cannot be checked. The choice location, and the diagonal line with choice. If (row + rowdelta> = size | row + rowdelta <0 | Col + coldelta> = size | Col + coldelta <0 | rowdelta = coldelta | Board [row + rowdelta] [col + coldelta]) continue; If (Board [row + rowdelta] [col + coldelta] = 0) // the blank space is next to choice, which is the valid ch Oicereturn 1 ;}}return 0;} void move (INT Board [] [size], int choice) {int choice_row = 0; // rowint choice_col storing choice = 0; // store choice's colint zero_row = 0; // store 0's rowint zero_col = 0; // store 0's colint temp = 0; int flag = 0; // mark if (! Is_valid (board, choice) return; For (choice_row = 0; choice_row <size; choice_row ++) // obtain choice's row, Col {for (choice_col = 0; choice_col <size; choice_col ++) {If (Board [choice_row] [choice_col] = choice) {flag = 1; break ;}} if (flag = 1) {flag = 0; break ;}for (zero_row = 0; zero_row <size; zero_row ++) // obtain the zero row, Col {for (zero_col = 0; zero_col <size; zero_col ++) {If (Board [zero_row] [zero_col] = 0) {flag = 1; break;} If (flag = 1) break;} swap (boar D [choice_row] [choice_col], Board [zero_row] [zero_col], temp); // swap number} int is_complete (INT Board [] [size]) {int ROW = 0; int Col = 0; int temp [size] [size] = {// used to check whether the original puzzle {1, 2, 3, 4} is defined after the puzzle is completed }, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 0}; For (ROW = 0; row <size; row ++) {for (COL = 0; col <size; Col ++) {If (Board [row] [col]! = Temp [row] [col]) return 0 ;}} return 1 ;}void initial (INT Board [] [size]) // The problem lies here, after initialization, the situation is very simple {int ROW = 0; int Col = 0; int flag = 0; // jump out of the loop marking int on_left [2] = {-1, 0 }; // offset int on_right [2] = {-} to the upper left corner; // offset int up = 0 to the upper right corner; // offset int left = 0 to the upper right corner; // offset to the left int right = 0; // offset to the right int rowdelta = 0; int coldelta = 0; int I = 0; // The cyclic variable Int J = 0; while (Board [0] [0] = 1) {for (;) {srand (Time (null); rowdelta = on_left [rand () % 2]; if (rowdelta = 0) {coldelta =-1; turn_left (Board); left ++;} else {coldelta = 0; turn_up (Board); up ++ ;} if (Left = 2) {// if you move it twice to the left, you should move it up 3-turn_upfor (I = 0; I <3-up; I ++) {turn_up (Board);} // move it to the left again. turn_left (Board); break;} If (up = 2) {// if it is moved up twice, 3-turn_leftfor (j = 0; j <3-left; j ++) {turn_left (board) ;}// move up turn_up (board) again ); break ;}}for (I = 0; I <3; I ++) // move down three steps {turn_down (Board);} up = 0; // initialize turn_upfor (;) // move to the upper right corner {srand (Time (null); rowdelta = on_right [rand () % 2]; If (rowdelta = 0) {coldelta = 1; turn_right (Board); Right ++;} else {coldelta = 0; turn_up (Board); up ++;} If (Right = 2) {// if you have shifted it twice to the right, you should move it up to 3-turn_upfor (I = 0; I <3-up; I ++) {turn_up (Board );} // move turn_right (Board); break;} If (up = 2) {// if it is moved up twice, 3-turn_rightfor (j = 0; j <3-right; j ++) {turn_right (board) ;}// move turn_up (board) up again ); break ;}} printf ("step = % d \ n", step);} void turn_left (INT Board [] [size]) {int ROW = 0; int Col = 0; int flag = 0; // obtain the coordinates of 0 for (ROW = 0; row <size; row ++) {for (COL = 0; col <size; Col ++) {If (Board [row] [col] = 0) {flag = 1; break ;}} if (flag = 1) {flag = 0; break ;}} total_choice [step ++] = Board [row] [col-1]; move (board, board [row] [col-1]);} void turn_right (INT Board [] [size]) {int ROW = 0; int Col = 0; int flag = 0; // obtain the coordinates of 0 for (ROW = 0; row <size; row ++) {for (COL = 0; Col <size; Col ++) {If (Board [row] [col] = 0) {flag = 1; break; }}if (flag = 1) {flag = 0; break ;}} total_choice [step ++] = Board [row] [col + 1]; move (Board, Board [row] [col + 1]);} void turn_up (INT Board [] [size]) {int ROW = 0; int Col = 0; int flag = 0; // obtain the coordinates of 0 for (ROW = 0; row <size; row ++) {for (COL = 0; Col <size; Col ++) {If (Board [row] [col] = 0) {flag = 1; break; }}if (flag = 1) {flag = 0; break ;}} total_choice [step ++] = Board [row-1] [col]; move (Board, Board [row-1] [col]);} void turn_down (INT Board [] [size]) {int ROW = 0; int Col = 0; int flag = 0; // obtain the coordinates of 0 for (ROW = 0; row <size; row ++) {for (COL = 0; Col <size; Col ++) {If (Board [row] [col] = 0) {flag = 1; break; }}if (flag = 1) {flag = 0; break ;}} total_choice [step ++] = Board [row + 1] [col]; move (Board, Board [row + 1] [col]);}
I recently wrote a jigsaw puzzle game with a square 4*4, as long
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 0
The number corresponds to the one above, and the puzzle is successful (0 is displayed with spaces, and only it can be moved, for example, it can only be changed between 12 and 15 and 0.
To move numbers)
I have completed the number movement function, but there is no good way to initialize the puzzle numbers (that is, randomly disrupt the order of numbers ).
I want to achieve that when a player cannot complete the puzzle, the computer will help move the number and display the process.
So I plan to move numbers randomly (not too many steps) on the computer and record these numbers so that the computer can restore the source image later.
I have thought of many ways to initialize the puzzle, but the effect is not ideal. The initialized graph is not messy enough, so that the player can spell out the image at once.
I have also implemented a method to make the initialization numbers messy, that is, to let the computer move randomly under the loop of while (the four corners of the image are not the original numbers ).
The generated puzzle is indeed messy, but it takes a long time. Generally, it loops around 10000000 steps. This is certainly unrealistic, even if the initialized puzzle is messy,
However, it is unrealistic to let the computer restore and display it, and the players will not be so patient.
The problem is that the initialization of the puzzle is not successful, and the generated puzzle is very simple. Because the code is not completely completed, the puzzle is automatically restored after being generated and press Enter.
Now it's modified, and it's basically ready to play.
# Include <stdio. h> # include <ctype. h> # include <stdlib. h> # include <time. h> # include <string. h> # define size 4 # define swap (X, Y, t) (t) = (x), (x) = (y), (y) = (t) int * total_choice = NULL; int step = 0; void display (INT Board [] [size]); // display the Board function int is_valid (INT Board [] [size], int choice ); // void move (INT Board [] [size], int choice) function used to determine whether a player is valid ); // function for moving numbers int is_complete (INT Board [] [size]); // void initial (int Board [] [size]); // initialize the void turn_left (INT Board [] [size]); // shift the left of the Computer void turn_right (INT Board [] [size]); // shift void turn_up (INT Board [] [size]) to the right of the computer; // move void turn_down (INT Board [] [size]) on the computer; // move void main () {int Board [size] [size] ={// the Board {, 3,4}, // initial values are reference numbers {5, 6, 7,8}, // used to select a vacant square for {9, 10, 11, 12}, // a turn {13, 14, 15, 0 }}; char again = 0; int choice = 0; int I = 0; int J = 0; Long Now = 0; int step = 36; char temp [4]; int capacity = 100; int * temp_choice = NULL; int temp_step = 0; int COUNT = 0; printf ("Welcome to simple jigsaw puzzle \ n"); printf ("select a number, which will be moved to the space \ n "); printf ("if this number cannot be moved, it will be displayed and the player will be re-elected to move the number \ n"); printf ("if the player cannot spell the source image, you can enter the password god, restored by computer \ n "); printf (" good luck! Press enter to start. \ n "); scanf (" % C ", & again); total_choice = (int *) malloc (capacity * sizeof (INT); If (total_choice = NULL) {printf ("out of memory! \ N "); abort () ;}do {COUNT = 0; for (I = 0; I <size; I ++) {for (j = 0; j <size; j ++) Board [I] [J] = ++ count;} Board [3] [3] = 0; total_choice = (int *) malloc (capacity * sizeof (INT); // allocate space for total_choice if (total_choice = NULL) {printf ("out of memory! \ N "); abort () ;}initial (Board); For (;) {If (step = capacity) {temp_step = step; Capacity + = 50; temp_choice = (int *) malloc (capacity * sizeof (INT); If (total_choice = NULL) {printf ("out of memory! \ N "); exit (1) ;}for (I = 0; I <temp_step; I ++) temp_choice [temp_step] = total_choice [temp_step]; free (total_choice ); total_choice = temp_choice; temp_choice = NULL;} display (Board); printf ("Enter the number you want to move:"); gets (temp); If (strcmp (temp, "God") = 0) {for (I = 0; I <step; I ++) {move (board, total_choice [step-i-1]); display (Board ); now = clock (); For (; clock ()-Now <clocks_per_sec;); System ("CLS") ;}free (total_choice); total_choice = NULL; break;} else {Choice = atoi (temp);} If (is_valid (board, choice) // if it is valid, move the number and display the result {move (board, choice ); total_choice [step ++] = choice; display (Board); System ("CLS"); // clear screen} else // if the movement is invalid, it is displayed as invalid mobile printf ("invalid mobile \ n"); If (is_complete (board) & is_valid (board, choice) {display (Board ); printf ("Good job! \ N "); printf (" mission completed! \ N "); free (total_choice); total_choice = NULL; break;} printf (" do you want to play it again? (Y or N) "); scanf (" % C ", & again); fflush (stdin);} while (tolower (again) = 'y ');} void display (INT Board [] [size]) {int ROW = 0; // row indexint Col = 0; // column indexfor (ROW = 0; row <size; row ++) {printf ("+"); For (COL = 0; Col <size; Col ++) printf ("---- + "); printf ("\ n"); For (COL = 0; Col <size; Col ++) printf ("| % 2D % s", Board [row] [col], board [row] [col]? "": "\ B"); // displays the number on the board. When the number is 0, it is displayed as a blank printf ("| \ n ");} printf ("+"); For (COL = 0; Col <size; Col ++) printf ("---- + "); // display the bottom lineprintf ("\ n"); // display the end of bottom line} int is_valid (INT Board [] [size], int choice) {int ROW = 0; int Col = 0; int rowdelta = 0; // row increment around a squareint coldelta = 0; // column increment around a squareint flag = 0; // jump out of the loop mark for (ROW = 0; row <size; row ++) // gets the position of the number selected by the player {for (c OL = 0; Col <size; Col ++) {If (Board [row] [col] = choice) {flag = 1; break ;}} if (flag = 1) break;} For (rowdelta =-1; rowdelta <= 1; rowdelta ++) {for (coldelta =-1; coldelta <= 1; coldelta ++) {// The out-of-boundary location cannot be checked. The choice location, and the diagonal line with choice. If (row + rowdelta> = size | row + rowdelta <0 | Col + coldelta> = size | Col + coldelta <0 | rowdelta = coldelta | Board [row + rowdelta] [col + coldelta] | rowdelta =-coldelta) continue; If (Board [row + rowdelta] [col + coldelta] = 0) // If the blank space is next to choice, it is valid choicereturn 1 ;}}return 0;} void move (INT Board [] [size], int choice) {int choice_row = 0; // rowint choice_col of choice storage = 0; // colint zero_row of choice storage = 0; // rowint zero_col of storage 0 = 0; // colint temp of storage 0 = 0; int flag = 0; // mark if (! Is_valid (board, choice) return; For (choice_row = 0; choice_row <size; choice_row ++) // obtain choice's row, Col {for (choice_col = 0; choice_col <size; choice_col ++) {If (Board [choice_row] [choice_col] = choice) {flag = 1; break ;}} if (flag = 1) {flag = 0; break ;}for (zero_row = 0; zero_row <size; zero_row ++) // obtain the zero row, Col {for (zero_col = 0; zero_col <size; zero_col ++) {If (Board [zero_row] [zero_col] = 0) {flag = 1; break;} If (flag = 1) break;} swap (boar D [choice_row] [choice_col], Board [zero_row] [zero_col], temp); // swap number} int is_complete (INT Board [] [size]) {int ROW = 0; int Col = 0; int temp [size] [size] = {// used to check whether the original puzzle {1, 2, 3, 4} is defined after the puzzle is completed }, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 0}; For (ROW = 0; row <size; row ++) {for (COL = 0; col <size; Col ++) {If (Board [row] [col]! = Temp [row] [col]) return 0 ;}} return 1 ;}void initial (INT Board [] [size]) // The problem lies here, after initialization, the situation is very simple {int ROW = 0; int Col = 0; int flag = 0; // jump out of the loop marking int on_left [2] = {-1, 0 }; // offset int on_right [2] = {-} to the upper left corner; // offset int up = 0 to the upper right corner; // offset int left = 0 to the upper right corner; // offset to the left int right = 0; // offset to the right int rowdelta = 0; int coldelta = 0; int I = 0; // The cyclic variable Int J = 0; srand (Time (null); step = 0; while (Board [0] [0] = 1) {for (;) {rowdelta = on_left [rand () % 2]; If (rowdelta = 0) {coldelta =-1; turn_left (Board); left ++;} else {coldelta = 0; turn_up (Board ); up ++;} If (Left = 2) {// if you move it twice to the left, you should move it up 3-turn_upfor (I = 0; I <3-up; I ++) {turn_up (Board);} // shift left again turn_left (Board); break;} If (up = 2) {// if it is moved up twice, it should be moved to the left 3-turn_leftfor (j = 0; j <3-left; j ++) {turn_left (Board );} // move up again turn_up (Board); break ;}}for (I = 0; I <3; I ++) // move down three steps {turn_down (Board);} up = 0; // initialize turn_upfor (;) // move {rowdelta = on_right [rand () to the upper right corner () % 2]; If (rowdelta = 0) {coldelta = 1; turn_right (Board); Right ++;} else {coldelta = 0; turn_up (Board ); up ++;} If (Right = 2) {// if you move it twice to the right, you should move it up 3-turn_upfor (I = 0; I <3-up; I ++) {turn_up (Board);} // move it right again. turn_right (Board); break;} If (up = 2) {// if it is moved up twice, it should be shifted to right 3-turn_rightfor (j = 0; j <3-right; j ++) {turn_right (Board );} // migrate turn_up (Board); break ;}for (I = 0; I <3; I ++) again) // move down step 3 {turn_down (board) ;}for (I = 0; I <2; I ++) // move 2 steps to the left {turn_left (board) ;}for (I = 0; I <3; I ++) // move up step 3 {turn_up (Board);} for (I = 0; I <2; I ++) // move step 2 to the right {turn_right (Board );} for (I = 0; I <3; I ++) // move three steps down {turn_down (Board);} turn_left (Board ); // move step 1 to the left for (I = 0; I <3; I ++) // move step 3 up {turn_up (Board);} turn_right (Board ); // move step 1 to the right (I = 0; I <3; I ++) // move step 3 down {turn_down (Board );}} void turn_left (INT Board [] [size]) {int ROW = 0; int Col = 0; int flag = 0; // obtain the coordinates of 0 for (ROW = 0; row <size; row ++) {for (COL = 0; Col <size; Col ++) {If (Board [row] [col] = 0) {flag = 1; break; }}if (flag = 1) {flag = 0; break ;}} total_choice [step ++] = Board [row] [col-1]; move (Board, Board [row] [col-1]);} void turn_right (INT Board [] [size]) {int ROW = 0; int Col = 0; int flag = 0; // obtain the coordinates of 0 for (ROW = 0; row <size; row ++) {for (COL = 0; Col <size; Col ++) {If (Board [row] [col] = 0) {flag = 1; break; }}if (flag = 1) {flag = 0; break ;}} total_choice [step ++] = Board [row] [col + 1]; move (Board, Board [row] [col + 1]);} void turn_up (INT Board [] [size]) {int ROW = 0; int Col = 0; int flag = 0; // obtain the coordinates of 0 for (ROW = 0; row <size; row ++) {for (COL = 0; Col <size; Col ++) {If (Board [row] [col] = 0) {flag = 1; break; }}if (flag = 1) {flag = 0; break ;}} total_choice [step ++] = Board [row-1] [col]; move (Board, Board [row-1] [col]);} void turn_down (INT Board [] [size]) {int ROW = 0; int Col = 0; int flag = 0; // obtain the coordinates of 0 for (ROW = 0; row <size; row ++) {for (COL = 0; Col <size; Col ++) {If (Board [row] [col] = 0) {flag = 1; break; }}if (flag = 1) {flag = 0; break ;}} total_choice [step ++] = Board [row + 1] [col]; move (Board, Board [row + 1] [col]);}
The running effect is as follows: