Linux Console version 2048

Source: Internet
Author: User
Tags clear screen getcolor signal handler strcmp

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

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.