It's interesting to see a Dutch Linux console version of 2048 written on GitHub, in C language.
The original URL is here.
Read his source code, feel good to write, the thick skin added some Chinese comments, the source code is as follows:
/* ============================================================================name:2048.cauthor:maurits Van der Scheedescription:console version of the game "2048" for gnu/linux============================================== ==============================*note by zhengmingpei,chinatime:2014.10.13contact:http:// zhengmingpei.github.comemail:[email protected]*/#define _xopen_source 500#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <termios.h> #include <stdbool.h > #include <stdint.h> #include <time.h> #include <signal.h> #define SIZE 4uint32_t score=0;uint8_t scheme=0;//gets the corresponding color based on value, copies the string containing the set terminal color to Colorvoid getColor (uint16_t value, char *color, size_t length) {//declares three color arrays, With a one-dimensional array, but each odd digit and even digit is composed of a front and back color//After two arrays corresponding to the program's startup option "Blackwhite", "bluered" uint8_t original[] = { 8,255,1,255,2,255,3,255,4,255,5,255,6,255,7,255,9,0,10,0,11,0,12,0,13,0,14,0,255,0,255,0};uint8_t blackwhite[] = {232,255,234,255,236,255,238,255,240,255,242,255,244,255,246,0,248,0,249,0,250,0,251,0,252,0,253,0,254,0,255,0};uint8_t Bluered[] = { 235,255,63,255,57,255,93,255,129,255,165,255,201,255,200,255,199,255,198,255,197,255,196,255,196,255,196,255,196,255,196 , 255};uint8_t *schemes[] = {original,blackwhite,bluered};uint8_t *background = schemes[scheme]+0;uint8_t *foreground = Schemes[scheme]+1;if (Value > 0) while (value >>= 1)//value moves one bit to the right until the value becomes 0, implementing each binary a different color {if (background+2< Schemes[scheme]+sizeof (original)) {background+=2;foreground+=2;}} Linux under terminal and Font color settings statement string snprintf (Color,length, "\033[38;5;%D;48;5;%DM", *foreground,*background);} Draw data Board, data board total 3x4 row, 7x4 column void Drawboard (uint16_t board[size][size]) {int8_t x,y;//\033[m: Close all Properties char color[40], reset[] = " \033[m ";//\033[h: Adjust cursor position printf (" \033[h ");p rintf (" 2048.c%17d pts\n\n ", score);//Data Board 3x4 Row, 7x4 column for (y=0;y<size;y++ {//First line print blank for (x=0;x<size;x++) {getColor (board[x][y],color,40);p rintf ("%s", color);p rintf ("");//reset reset to avoid non-data Plate part madeTo affect printf ("%s", reset);} printf ("\ n");//The number of times the line is printed, the number centered for (x=0;x<size;x++) {getColor (board[x][y],color,40);p rintf ("%s", color); if (Board[x] [Y]!=0] {char s[8];//note here, is board[x][y] instead of yxsnprintf (s,8, "%u", Board[x][y]), int8_t t = 7-strlen (s);p rintf ("%*s%s%*s", T-T/2, "", S,t/2, "");} else {printf ("· ");} printf ("%s", reset);} printf ("\ n");//last line print blank for (x=0;x<size;x++) {getColor (board[x][y],color,40);p rintf ("%s", color);p rintf (""); printf ("%s", reset);} printf ("\ n");} printf ("\ n");p rintf ("←,↑,→,↓or q \ n");//suspect carriage return to printf ("\033[a");} Find the coordinates of the number of x left to be merged in the one-dimensional array, stop is checkpoint int8_t findtarget (uint16_t array[size],int8_t x,int8_t stop) {int8_t t;//if x is the first number, the left is numerous, Directly returns x if (x==0) {return x;} Traverse X to the left of the coordinate for (t=x-1;t>=0;t--) {//merge algorithm: The number at//1.t is not 0 and the number at x is not equal, the number returned at t+1//2.t is not 0 and the number at x is equal, and the number returned at t//3.t is 0. Based on stop to determine whether to look forward, prevent multiple merges if (array[t]!=0) {if (Array[t]!=array[x]) {//merge is not possible, take next Positionreturn t+1;} return t;} else {//We should not slide further, return this oneif (t==stop) {return t;}}} WE did not find Areturn x;} Move a one-dimensional array bool Slidearray (uint16_t Array[size]) {bool success = false;//declares the current position, the location to be merged, Checkpoint int8_t X,t,stop=0;for (x=0;x <size;x++) {if (array[x]!=0) {t = Findtarget (array,x,stop);//If the position to be merged is not equal to the current position, move or merge//if Target is not original POS Ition, then move or Mergeif (t!=x) {//If the position to be merged is not 0, move right to checkpoint stop//if Target is not zero, set stop to avoid double mergeif (AR ray[t]!=0) {score+=array[t]+array[x];stop = t+1;} Array[t]+=array[x];array[x]=0;success = True;}}} return success;} Rotate the data board, rotate 90 degrees to the right so that you can move the array in one Direction indirectly control the movement of the four-direction void Rotateboard (uint16_t board[size][size]) {int8_t i,j,n=size;uint16_t tmp;//ring rotation, first outside and inside, first left and right for (i=0; i<n/2; i++) {for (j=i; j<n-i-1; J + +) {tmp = Board[i][j];board[i][j] = board[j][n-i-1]; BOARD[J][N-I-1] = board[n-i-1][n-j-1];board[n-i-1][n-j-1] = board[n-j-1][i];board[n-j-1][i] = tmp;}}} Move up the data board bool MoveUp (uint16_t Board[size][size]) {bool success = false;int8_t X;for (x=0;x<size;x++) {// Do a move or merge on each column,//Here is a column instead of a row, related to the previous output order success |= Slidearray (BOARD[X]);//If there is a list of successes, Success}return success;} Shift left: Rotate 90 degrees to the right, merge up, then rotate 3 90 degrees bool MoveLeft (uint16_t Board[size][size]) {bool Success;rotateboard (board); success = MoveUp (board); Rotateboard (board); Rotateboard (board); Rotateboard (board); return success;} Move Down: Rotate 2 90 degrees to the right, merge up, and then rotate 2 90 degrees bool MoveDown (uint16_t Board[size][size]) {bool Success;rotateboard (board); Rotateboard (board); success = moveUp (board); Rotateboard (board); Rotateboard (board); return success;} Shift right: Rotate 3 90 degrees to the right, merge up, and then rotate 1 90 degrees bool MoveRight (uint16_t Board[size][size]) {bool Success;rotateboard (board); Rotateboard (board); Rotateboard (board); success = moveUp (board); Rotateboard (board); return success;} BOOL Findpairdown (uint16_t Board[size][size]) {bool success = false;int8_t X,y;for (x=0;x<size;x++) {for (y=0;y< size-1;y++) {if (board[x][y]==board[x][y+1]) return true;}} return success;} Calculates whether the data board is full int16_t countempty (uint16_t board[size][size]) {int8_t x,y;int16_t count=0;for (x=0;x<size;x++) {for (y= 0;y<size;y++) {if (board[x][y]==0) {count++;}}} return count;} Check whether the game ends bool Gameended (uint16_t Board[size][size]) {bool ended = true;//If there is a vacancy, the IF is not closed (countempty (board) >0) return F alse;//transverse check, have equal neighbors, not End if (Findpairdown (board)) return False;rotateboard (board);//rotate once, longitudinal check, have equal neighbors, not end if ( Findpairdown (board)) ended = False;rotateboard (board); Rotateboard (board); Rotateboard (board); return ended;} Randomly resets the data board void Addrandom (uint16_t board[size][size]) {//global variable, whether the static bool initialized = false;//x, y coordinates int8_t x,y;// R random position, len all empty data board data length int16_t r,len=0;//n random data, list all empty data board locations uint16_t N,list[size*size][2];if (!initialized) {Srand ( Time (NULL)); initialized = true;} Locate all empty coordinates for (x=0;x<size;x++) {for (y=0;y<size;y++) {if (board[x][y]==0) {list[len][0]=x;list[len][1]=y) on the data board; len++;}}} If there is an empty case, the data is populated if (len>0) {r = rand ()%len;x = List[r][0];y = List[r][1];n = ((rand ()%10)/9+1) *2;board[x][y]=n;}} Set input mode, toggle void Setbufferedinput (bool enable) {static BOOL enabled = true;static struct Termios old;struct termi in row and unbuffered OS New;iF (Enable &&!enabled) {//Restore the former settingstcsetattr (stdin_fileno,tcsanow,&old);//Set the new stat eenabled = true;} else if (!enable && enabled) {//Get the terminal settings for Standard inputtcgetattr (stdin_fileno,&new);//W e want to keep the old setting to restore them at the Endold = new;//Disable canonical mode (buffered I/O) and local echo New.c_lflag &= (~icanon & ~echo);//Set the new settings immediatelytcsetattr (stdin_fileno,tcsanow,&new);// Set the new stateenabled = FALSE;}} int Test () {uint16_t array[size];uint16_t data[] = { 0,0,0,2,2,0,0,0,0,0,2,2,4,0,0,0,0,2,0,2,4,0,0,0,2,0,0,2,4,0,0,0,2,0,2,0,4,0,0,0,2,2,2,0,4,2,0,0,2,0,2,2,4,2,0,0,2,2,0,2,4 , 2,0,0,2,2,2,2,4,4,0,0,4,4,2,2,8,4,0,0,2,2,4,4,4,8,0,0,8,0,2,2,8,4,0,0,4,0,2,2,4,4,0,0};uint16_t *in,*out; uint16_t t,tests;uint8_t I;bool success = True;tests = (sizeof (data)/sizeof (Data[0])/(2*size); for (t=0;t<tests;t++ ) {in = Data+t*2*size;out = in + size;for (i=0;i<size;i++) {ARRay[i] = In[i];} Slidearray (array), for (i=0;i<size;i++) {if (Array[i]! = Out[i]) {success = false;}} if (Success==false) {for (i=0;i<size;i++) {printf ("%d", In[i]);} printf ("= ="); for (i=0;i<size;i++) {printf ("%d", Array[i]);} printf ("expected"); for (i=0;i<size;i++) {printf ("%d", In[i]);} printf ("= ="); for (i=0;i<size;i++) {printf ("%d", Out[i]);} printf ("\ n"); break;}} if (success) {printf ("All%u tests executed successfully\n", tests);} return!success;} void Signal_callback_handler (int signum) {printf ("TERMINATED \ n"), Setbufferedinput (True);p rintf ("\033[?25 H "); exit (Signum);} int main (int argc, char *argv[]) {uint16_t Board[size][size];char c;bool success;if (argc = = 2 && strcmp (argv[1], " Test ") ==0) {return Test ();} if (argc = = 2 && strcmp (argv[1], "Blackwhite") ==0) {scheme = 1;} if (argc = = 2 && strcmp (argv[1], "bluered") ==0) {scheme = 2;} 33[?25l Hide cursor//33[2j Clear Screen//33[h set cursor position printf ("\033[?25l\033[2j\033[h");//register Signal Handler FOr when the ctrl-c is Pressedsignal (SIGINT, Signal_callback_handler);//data is cleared to 0memset (board,0,sizeof (board));//Add two random numbers, Because 2 random number Addrandom (board) are generated during initialization, addrandom (board);//Draw Data Board Drawboard (board)//disable cache input, terminal supports read by character and does not echo Setbufferedinput ( FALSE);//game main loop while (true) {C=getchar (), switch (c) {case 97://' a ' keycase 104://' h ' keycase 68://left arrowsuccess = mo Veleft (board); Break;case 100://' d ' keycase 108://' l ' keycase 67://right arrowsuccess = moveright (board); Break;case 119://' W ' keycase 107://' K ' keycase 65://up arrowsuccess = moveUp (board); Break;case 115://' s ' keycase 106://' j ' keycase 66://down arrowsuccess = movedown (board); Break;default:success = false;} If the merge succeeds, then redraw if (success) {Drawboard (board); Usleep (150000); Addrandom (board);d Rawboard (board); if (gameended (board)) {printf ("GAME over \"); break;}} If the input is Q, open the row buffer and display the cursor if (c== ' Q ') {printf ("QUIT?"). (y/n) \ n "), while (true) {C=getchar (), if (c== ' y ') {Setbufferedinput (true);p rintf (" \033[?25h "); exIt (0);} else {drawboard (board); break;}}} if (c== ' R ') {printf ("RESTART? (y/n) \ n "), while (true) {C=getchar (); if (c== ' y ') {memset (board,0,sizeof (board)); Addrandom (board); Addrandom (board); Drawboard (board); break;} else {drawboard (board); break;}}} Setbufferedinput (True);p rintf ("\033[?25h"); return exit_success;}
Linux Console version 2048