johnny.tifosi Δημοσ. 19 Ιουνίου 2014 Δημοσ. 19 Ιουνίου 2014 (επεξεργασμένο) Καλησπέρα, πωρώθηκα πρόσφατα με το 2048 και σκέφτηκα με τις λίγες γνώσεις C που έχω και συμπληρώντας τα δύσκολα (χρωματιστό κείμενο, διάβασμα arrow keys) με κώδικα που βρίσκω στο google να γράψω ένα απλό προγραμματάκι με το DevC++ που να παίζει σε κονσόλα εκτυπώνοντας κέιμενο. Έχω γράψει σχεδόν όλο τον κώδικα. Αυτό που λέιπει είναι οι υπολογισμοί που κάνει το παιχνιδι σε κάθε μια από τις 4 κινήσεις (πάνω κατω αριστερά δεξιά) διαβάζοντας τα βελάκια. Για την ακρίβεια, ξεκίνησα γράφοντας τον κώδικα για το "πανω" και το πρόγραμμα δεν αντιδρά. Πατώντας τα άλλα τρια βελάκια που δεν κάνουν τίποτα προς το παρόν το προγραμμα προχωρά κανονικά και βάζει νέο αριθμό στον πίνακα. Παραθέτω τον κώδικα εδώ: https://github.com/johnnytifosi/2048/blob/master/main.c το επίμαχο σημείο είναι στις γραμμές 118-147, μπορεί όμως να πέφτει και σε infinite loop από την γεννήτρια τυχαίων αριθμών ψάχνοντας νέο άδειο κελί. επλίζω ότι ο σχολιασμός του κώδικα είναι επαρκής, έτσι κι αλλιώς είναι αρκετά σύντομος. Οποιαδήποτε βοήθεια είναι ευπρόσδεκτη. edit: συγγνώμη για το διπλό θέμα. ας σβηστεί από τους mods Επεξ/σία 19 Ιουνίου 2014 από johnny.tifosi
Star_Light Δημοσ. 20 Ιουνίου 2014 Δημοσ. 20 Ιουνίου 2014 void print(int x) { HANDLE hConsole; int k; if (x==0) { k=15;} else if (x==2) { k=112;} else if (x==4) { k=48;} else if (x==8) { k=32;} else if (x==16) { k=208;} else if (x==32) { k=192;} else if (x==64) { k=64;} else { k=224;} hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, k); if (x<10) { printf(" %d ",x);} else if (x<100) { printf(" %d ",x);} else if (x<1000) { printf(" %d ",x);} else { printf(" %d",x);} SetConsoleTextAttribute(hConsole, 7); } για κάποιο λογο ολα αυτα τα magic numbers μεσα στα if else μου φαινονται άσχημα.
migf1 Δημοσ. 20 Ιουνίου 2014 Δημοσ. 20 Ιουνίου 2014 Καλησπέρα, πωρώθηκα πρόσφατα με το 2048 και σκέφτηκα με τις λίγες γνώσεις C που έχω και συμπληρώντας τα δύσκολα (χρωματιστό κείμενο, διάβασμα arrow keys) με κώδικα που βρίσκω στο google να γράψω ένα απλό προγραμματάκι με το DevC++ που να παίζει σε κονσόλα εκτυπώνοντας κέιμενο. Έχω γράψει σχεδόν όλο τον κώδικα. Αυτό που λέιπει είναι οι υπολογισμοί που κάνει το παιχνιδι σε κάθε μια από τις 4 κινήσεις (πάνω κατω αριστερά δεξιά) διαβάζοντας τα βελάκια. Για την ακρίβεια, ξεκίνησα γράφοντας τον κώδικα για το "πανω" και το πρόγραμμα δεν αντιδρά. Πατώντας τα άλλα τρια βελάκια που δεν κάνουν τίποτα προς το παρόν το προγραμμα προχωρά κανονικά και βάζει νέο αριθμό στον πίνακα. Παραθέτω τον κώδικα εδώ: https://github.com/johnnytifosi/2048/blob/master/main.c το επίμαχο σημείο είναι στις γραμμές 118-147, μπορεί όμως να πέφτει και σε infinite loop από την γεννήτρια τυχαίων αριθμών ψάχνοντας νέο άδειο κελί. επλίζω ότι ο σχολιασμός του κώδικα είναι επαρκής, έτσι κι αλλιώς είναι αρκετά σύντομος. Οποιαδήποτε βοήθεια είναι ευπρόσδεκτη. edit: συγγνώμη για το διπλό θέμα. ας σβηστεί από τους mods Το πρόβλημα φαίνεται να είναι πως δεν καθαρίζεις τον temp πριν από κάθε iteration στήλης. Με ένα memset(temp, 0, size * sizeof(int) ); δείχνει πως έστρωσε. Πέρα από αυτό, μου βγήκαν λιγάκι τα μάτια για να διαβάσω τον κώδικά σου (έως πολύ ). Και τα σχόλια δεν θα έλεγα ότι βοήθησαν ιδιαίτερα. Χρειάστηκε να καθαρογράψω αρκετό από την κώδικά σου μέχρι να βγάλω άκρη. Anyway, αφού έβγαλα άκρη τελικά, ψιλο-πορώθηκα και το συνέχισα λιγάκι. Κώδικας: 2048.c #include <stdio.h> #include <stdlib.h> //#include <conio.h> #include <time.h> #include <windows.h> #include "my.h" #define SIZE 4 /* -------------------------------------------------------------- * * -------------------------------------------------------------- */ void board_init( int board[SIZE][SIZE] ) { memset( board, 0, SIZE*SIZE * sizeof(int) ); } /* -------------------------------------------------------------- * Print specified board element in colors and with correct spacing * -------------------------------------------------------------- */ void board_print_elem_at( int board[SIZE][SIZE], int i, int j ) { HANDLE hConsole; int elem = board[i][j]; int k; switch ( elem ) { case 0: k = 15; break; case 2: k = 112; break; case 4: k = 48; break; case 8: k = 32; break; case 16: k = 208; break; case 32: k = 192; break; case 64: k = 64; break; default: k = 224; break; } hConsole = GetStdHandle( STD_OUTPUT_HANDLE ); SetConsoleTextAttribute( hConsole, k ); if ( elem < 10) { printf( " %d ", elem ); } else if ( elem < 100 ) { printf( " %d ", elem ); } else if ( elem < 1000 ) { printf( " %d ", elem ); } else { printf( " %d", elem ); } fflush( stdout ); SetConsoleTextAttribute(hConsole, 7); } /* -------------------------------------------------------------- * * -------------------------------------------------------------- */ void board_print( int board[SIZE][SIZE] ) { int i,j; for (i=0; i < SIZE; i++) { for (j=0; j < SIZE; j++) { board_print_elem_at( board, i,j ); } putchar( '\n' ); } } /* -------------------------------------------------------------- * Insert a random number at a random empty slot of the board * -------------------------------------------------------------- */ void board_generate_elem( int board[SIZE][SIZE], int *nempty ) { int i, j; do { i = rand() % SIZE; j = rand() % SIZE; } while ( 0 != board[i][j] ); board[i][j] = 0 == rand() % 2 ? 2 : 4; /* val must be 2 or 4 */ (*nempty)--; } /* -------------------------------------------------------------- * Return 1 (true) if at least one upwards move is available to be * played, so the caller can generate a new board element. If no * move played, or no more moves are available, the function returns * 0 (false). * -------------------------------------------------------------- */ int do_key_up( int board[SIZE][SIZE], int *score, int *nempty ) { int i,j,k; int temp[SIZE] = {0}; int played = 0; /* for every column */ for ( j=0; j < SIZE; j++) { /* if 2 consecutive cells contain 0 and non-0 in * any order, then a move is available */ for (i=0; i < SIZE-1; i++) { if ( 0 == board[i][j] && 0 != board[i+1][j] ) { played = 1; break; } } /* backup non-zero elems into temp buf, and zero them */ memset( temp, 0, SIZE * sizeof(int) ); for (i=0, k=0; i < SIZE; i++) { if ( 0 != board[i][j] ) { temp[k++] = board[i][j]; board[i][j] = 0; } } /* in temp, merge adjacent equal cells (if temp has at * least one equal adjacent pair, then a move is available) */ for (k=0; k < SIZE-1; k++) { if ( 0 == temp[k] ) { continue; } if ( temp[k] == temp[k+1] ) { temp[k] += temp[k+1]; temp[k+1] = 0; (*score) += temp[k]; k++; (*nempty)++; played = 1; } } /* copy all non-zero elems of temp * back to the current column (j), * without any gaps between them */ for (k=0,i=0; k < SIZE; k++) { if ( 0 != temp[k] ) { board[i++][j] = temp[k]; } } /* If after the merging, there are still equal * adjacent cells, played is set to 1 (true) so * the caller can generate a new board element. * The new merging will happen the next time * this function is called. */ for (i=0; i < SIZE-1; i++) { if ( 0 == board[i][j] ) { continue; } if ( board[i][j] == board[i+1][j] ) { played = 1; break; } } } return played; } /* -------------------------------------------------------------- * * -------------------------------------------------------------- */ int do_key_down( int board[SIZE][SIZE], int *score, int *nempty ) { puts( "DOWN" ); return 0; } /* -------------------------------------------------------------- * * -------------------------------------------------------------- */ int do_key_left( int board[SIZE][SIZE], int *score, int *nempty ) { puts( "LEFT" ); return 0; } /* -------------------------------------------------------------- * * -------------------------------------------------------------- */ int do_key_right( int board[SIZE][SIZE], int *score, int *nempty ) { puts( "RIGHT" ); return 0; } /* -------------------------------------------------------------- * * -------------------------------------------------------------- */ /** * run this program using the console pauser * or add your own getch, system("pause") * or input loop */ int main( void ) { int board[SIZE][SIZE]; /* the 4x4 matrix */ int played; /* was a move played? */ int nempty; /* number of currently empty slots */ int score; int key; /* user keypress (see my.h) */ unsigned int keymask = 0x00; /* indicates Arrow and/or Function Keys */ score = 0; played = 1; /* true */ nempty = SIZE * SIZE; srand( time( NULL ) ); /* seed PRNG with current time */ board_init( board ); board_generate_elem( board, &nempty ); board_generate_elem( board, &nempty ); while ( 0 != nempty ) { my_cls(); board_print( board ); printf( "Score: %d\n", score ); key = my_getch( &keymask ); if ( MY_KEY_ESCAPE == key ) { break; } if ( keymask & MY_KEYMASK_ARROW ) { //puts( "arrow key" ); switch( key ) { case MY_KEY_UP: played = do_key_up( board, &score, &nempty ); break; case MY_KEY_DOWN: played = do_key_down( board, &score, &nempty ); break; case MY_KEY_LEFT: played = do_key_left( board, &score, &nempty ); break; case MY_KEY_RIGHT: played = do_key_right( board, &score, &nempty ); break; } printf( "played: %d\n", played ); if ( played ) { board_generate_elem( board, &nempty ); } } } my_cls(); board_print( board ); printf( "Score: %d\n", score ); puts( "GAME OVER" ); system( "pause" ); return 0; } Τα getch() και cls() τα χρησιμοποιώ από ένα πρόχειρο 2ο αρχείο που το λέω my.c, και τα πήρα σχεδόν copy & paste από ένα cross-platform console user interface που είχα φτιάξει παλαιότερα σε C++ (δεν το έχω ολοκληρώσει)... Κώδικας: my.h #ifndef MY_H #define MY_H /* Determine compilation OS */ #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) || defined(__TMY_OS_WIN__) #define MY_OS_WINDOWS #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) #define MY_OS_LINUX #elif defined(__unix__) || defined(__unix) || defined(unix) \ || defined(__CYGWIN__) || ( defined(__APPLE__) && defined(__MACH) ) #define MY_OS_UNIX #else #define MY_OS_UNKNOWN #endif /* ------------- * Includes * ------------- */ #if defined( MY_OS_WINDOWS ) #include <conio.h> #include <windows.h> #elif defined( MY_OS_UNIX ) || defined( MY_OS_LINUX ) #include <sys/ioctl.h> #include <termios.h> #include <unistd.h> #endif /* ------------- * Constants * ------------- */ enum { /* unbufferd i/o related constants & masks */ MY_KEYMASK_RESET = 0x00, MY_KEYMASK_ARROW = (1 << 0), // 0x01 MY_KEYMASK_FKEY = (1 << 1), // 0x02 MY_KEYMASK_UNKNOWN = (1 << 2), // 0x04 MY_KEY_NUL = 0, MY_KEY_ESCAPE = 27, MY_KEY_ENTER = 13, MY_KEY_SPACE = 32, MY_KEY_UP = 72, MY_KEY_DOWN = 80, MY_KEY_LEFT = 75, MY_KEY_RIGHT = 77, MY_KEY_INSERT = 82, MY_KEY_DELETE = 83, MY_KEY_HOME = 71, MY_KEY_END = 79, MY_KEY_PAGE_UP = 73, MY_KEY_PAGE_DOWN = 81, MY_KEY_BACKSPACE = 8, MY_KEY_F1 = 59, MY_KEY_F2 = 60, MY_KEY_F3 = 61, MY_KEY_F4 = 62, MY_KEY_F5 = 63, MY_KEY_F6 = 64, MY_KEY_F7 = 65, MY_KEY_F8 = 66, MY_KEY_F9 = 67, MY_KEY_F10 = 68, MY_KEY_F11 = 133, MY_KEY_F12 = 134 }; #ifndef MY_C extern int my_getch( unsigned int *outKeyMask ); extern int my_cls( void ); #endif #endif Κώδικας: my.c #define MY_C #include <stdio.h> #include "my.h" /* -------------------------------------------------------------- * * -------------------------------------------------------------- */ int my_getch( unsigned int *outKeyMask ) { int key; *outKeyMask = MY_KEYMASK_RESET; #if defined( MY_OS_WINDOWS ) /* on Windows platforms */ key = getch(); if ( 0 == key ) /* FunctionKey*/ { *outKeyMask |= MY_KEYMASK_FKEY; key = getch(); } else if ( 224 == key /* ArrowKey */ ){ *outKeyMask |= MY_KEYMASK_ARROW; key = getch(); } #elif defined( MY_OS_UNIX ) || defined( MY_OS_LINUX ) /* on Linux & Unix platforms */ #define MY_MAGIC_MAX_CHARS 18 struct termios oldt, newt; unsigned char keycodes[ MY_MAGIC_MAX_CHARS ] = {'\0'}; int count; /* get the terminal settings for stdin */ tcgetattr( STDIN_FILENO, &oldt ); /* we want to keep the old setting to restore them at the end */ newt = oldt; /* ? */ newt.c_cc[ VMIN ] = MY_MAGIC_MAX_CHARS; newt.c_cc[ VTIME ] = 1; newt.c_iflag &= ~(IXOFF); /* disable canonical mode (buffered i/o) and local echo */ newt.c_lflag &= ~(ECHO | ICANON); /* set the new settings */ // tcsetattr( STDIN_FILENO, TCSAFLUSH, &newt ); tcsetattr( STDIN_FILENO, TCSANOW, &newt ); count = read( fileno(stdin), keycodes, MY_MAGIC_MAX_CHARS ); if ( 1 == count ) { key = keycodes[0]; if ( '\r' == key || '\n' == key ) { key = MY_KEY_ENTER; } else if ( '\b' == key || 127 == key ) { key = MY_KEY_BACKSPACE; } } else { if ( '\r' == keycodes[0] || '\n' == keycodes[0] ) { key = MY_KEY_ENTER; } // arrow keys else if (0 == memcmp(&keycodes[1], "[A", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_UP; } else if (0 == memcmp(&keycodes[1], "[B", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_DOWN; } else if (0 == memcmp(&keycodes[1], "[C", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_RIGHT; } else if (0 == memcmp(&keycodes[1], "[D", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_LEFT; } // insert & delete keys else if (0 == memcmp(&keycodes[1], "[2~", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_INSERT; } else if (0 == memcmp(&keycodes[1], "[3~", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_DELETE; } // home & end keys else if (0 == memcmp(&keycodes[1], "OH", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_HOME; } else if (0 == memcmp(&keycodes[1], "OF", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_END; } // page-up & page-down keys else if (0 == memcmp(&keycodes[1], "[5~", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_PAGE_UP; } else if (0 == memcmp(&keycodes[1], "[6~", count-1) ) { *outKeyMask |= MY_KEYMASK_ARROW; key = MY_KEY_PAGE_DOWN; } // FKEYS else if (0 == memcmp(&keycodes[1], "OP", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F1; } else if (0 == memcmp(&keycodes[1], "OQ", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F2; } else if (0 == memcmp(&keycodes[1], "OR", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F3; } else if (0 == memcmp(&keycodes[1], "OS", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F4; } else if (0 == memcmp(&keycodes[1], "[15~", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F5; } else if (0 == memcmp(&keycodes[1], "[17~", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F6; } else if (0 == memcmp(&keycodes[1], "[18~", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F7; } else if (0 == memcmp(&keycodes[1], "[19~", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F8; } else if (0 == memcmp(&keycodes[1], "[20~", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F9; } else if (0 == memcmp(&keycodes[1], "[24~", count-1) ) { *outKeyMask |= MY_KEYMASK_FKEY; key = MY_KEY_F12; } // other multi-character ANSI escape sequences else { *outKeyMask |= MY_KEYMASK_UNKNOWN; key = -(int)keycodes[count-1]; } } /* restore the former settings */ tcsetattr ( STDIN_FILENO, TCSANOW, &oldt ); #else /* On Unsupported Platforms, fall-back to bufferd getchar() */ key = getchar(); #endif return key; } /* ----------------------------------------------------- * Cross-platform function to clear the standard output. * * It works both on the Windows console and on terminals that * support ANSI escape sequences (that is on most Unix/Linux * terminals). * -------------------------------------------------------------- */ int my_cls( void ) { #if defined( MY_OS_WINDOWS ) HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); COORD coordScreen = {0, 0}; /* home for the cursor */ DWORD cCharsWritten; CONSOLE_SCREEN_BUFFER_INFO csbi; DWORD dwConSize; if ( INVALID_HANDLE_VALUE == hConsole) { return 0; } // get the number of character cells in the current buffer if ( !GetConsoleScreenBufferInfo(hConsole, &csbi) ) { return 0; } dwConSize = csbi.dwSize.X * csbi.dwSize.Y; // fill the entire screen with blanks if ( !FillConsoleOutputCharacter( hConsole, /* Handle to console screen buffer */ (TCHAR) ' ', /* Character to write to the buffer */ dwConSize, /* Number of cells to write */ coordScreen, /* Coordinates of first cell */ &cCharsWritten ) /* Receive number of characters written */ ){ return 0; } // get the current text attribute if ( !GetConsoleScreenBufferInfo(hConsole, &csbi) ) { return 0; } // set the buffer's attributes accordingly if ( !FillConsoleOutputAttribute( hConsole, /* Handle to console screen buffer */ csbi.wAttributes, /* Character attributes to use */ dwConSize, /* Number of cells to set attribute */ coordScreen, /* Coordinates of first cell */ &cCharsWritten ) /* Receive number of characters written */ ){ return 0; } // put the cursor at its home coordinates if ( !SetConsoleCursorPosition(hConsole, coordScreen) ) { return 0; } #elif defined( MY_OS_UNIX ) || defined( MY_OS_LINUX ) printf( "%s%s", "\033[2J", "\033[H" ); fflush( stdout ); #else /* On Unsupported Platforms */ for (int i=0; i < 24; i++) putchar( '\n' ); #endif return 1; } Βασικά δεν ξέρω αν δουλεύει σωστά ως λογική το game, τέτοια ώρα που είναι δεν ασχολήθηκα με αλγόριθμους. Αυτό που είχες εσύ κράτησα, κι απλώς προσέθεσα μερικά παραπάνω chekcs για την τιμή επιστροφής της do_key_up(). Τέλος, για να κάνεις και το τελευταίο κομμάτι που έχει μείνει (δηλαδή τα χρώματα) cross-platform, μπορείς αν θέλεις να χρησιμοποιήσεις ένα απλό στη χρήση σχετικό user-interface, που είχα φτιάξει αποκλειστικά στον προεπεξεργαστή της C. Μπορείς να βρεις εδώ την έκδοση 1.03, αλλά είχα κάνει και έκδοση 1.04(h2)-alpha που δεν την κυκλοφόρησα (το λινκ σε πάει στην online τεκμηρίωσή της, αλλά αν τη θέλεις πες μου να σου την στείλω με p.m.) Καλή συνέχεια. 1
johnny.tifosi Δημοσ. 20 Ιουνίου 2014 Μέλος Δημοσ. 20 Ιουνίου 2014 (επεξεργασμένο) Ευχαριστώ για τις απαντήσεις. 1. Τα μαγικά νούμερα είναι από τα λίγα πράγματα που είναι σίγουρα σωστά. Είναι απλοί κωδικοί για χρώματα. 2. Όντως το κύριο πρόβλημα ήταν ότι ξέχασα να αρχικοποιήσω τον temp με μηδενικά και η συναρτηση insert επεφτε σε infinite loop. διόρθωσα και λίγα πράγματα στην λογική ακόμη και τα ξαναανέβασα στο αρχικό λινκ του github. Βεβαια το παιχνίδι ακόμη δεν δουλεύει σωστά (βάζει πάνω από έναν νέους αριθμούς σε κάποιους γύρους, δέχεται άκυρες κινήσεις κλπ) αλλά δείχνει κάποιες σωστές αντιδράσεις. όταν βρω χρόνο θα διαβάσω τον κώδικά σου migf1.Τα χρώματα είχα διαβάσει ότι ισχύουν μόνο για windows, θα διαβάσω αυτά που μου έστειλες αν και δεν με πολυενδιαφέρει πολύ το cross-platform του θέματος. Το πολύ πολύ αν ένας φίλος μου έχει όρεξη μπορεί να του το δώσω να το δουλέψει σε android. edit: νομίζω ότι έχω διορθώσει πλέον όλα τα bugs. ορίστε και μια έτοιμη έκδοση για άμεσο κάψιμο! 2048.zip Επεξ/σία 20 Ιουνίου 2014 από johnny.tifosi 4
bnvdarklord Δημοσ. 20 Ιουνίου 2014 Δημοσ. 20 Ιουνίου 2014 Ωραίο, δειχνει να δουλευει σωστα. Μια απορία εχω - πως γινεται το .exe που δινεις να ειναι 400ΚΒ, ενώ αυτο που εκανα εγω compile με το gcc να ειναι 90ΚΒ;
johnny.tifosi Δημοσ. 20 Ιουνίου 2014 Μέλος Δημοσ. 20 Ιουνίου 2014 Ωραίο, δειχνει να δουλευει σωστα. Μια απορία εχω - πως γινεται το .exe που δινεις να ειναι 400ΚΒ, ενώ αυτο που εκανα εγω compile με το gcc να ειναι 90ΚΒ; Δεν έχω ιδέα
Anubis13 Δημοσ. 20 Ιουνίου 2014 Δημοσ. 20 Ιουνίου 2014 Ωραίο, δειχνει να δουλευει σωστα. Μια απορία εχω - πως γινεται το .exe που δινεις να ειναι 400ΚΒ, ενώ αυτο που εκανα εγω compile με το gcc να ειναι 90ΚΒ; Διαφορετικα compile parameters? Πιθανη εκδοχη..Πχ σε ιδιο προγραμμα gcc μπλα μπλα με gcc -std=c99 αλλαζει τα πραγματα
gon1332 Δημοσ. 20 Ιουνίου 2014 Δημοσ. 20 Ιουνίου 2014 Διαφορετικα compile parameters? Πιθανη εκδοχη..Πχ σε ιδιο προγραμμα gcc μπλα μπλα με gcc -std=c99 αλλαζει τα πραγματα Επίσης οι πολλές βελτιστοποιήσεις compilers αυξάνουν το μέγεθος κατά πολύ.
bnvdarklord Δημοσ. 20 Ιουνίου 2014 Δημοσ. 20 Ιουνίου 2014 Διαφορετικα compile parameters? Πιθανη εκδοχη..Πχ σε ιδιο προγραμμα gcc μπλα μπλα με gcc -std=c99 αλλαζει τα πραγματα Τόσο μεγάλη διαφορά όμως; Με c99 δεν κανει compile, και με -O1 ή -Ο2 το μεγεθος αλλάζει ελάχιστα. Μπορει να έχει σχέση η έκδοση του gcc; Εγω έχω την 4.8.1.
migf1 Δημοσ. 22 Ιουνίου 2014 Δημοσ. 22 Ιουνίου 2014 @tifosi: Ωραίος. Αν ευκαιρήσω αργότερα, θα δω μήπως το ντύσω με x-platform χρώματα και του βάλω να κρατάει και best-score. @bnvdarklord: Δοκίμασε να βάλεις -s flag στον gcc (κάνει strip τα symbols από το εκτελέσιμο). Επιπρόσθετα, μπορείς να δοκιμάσεις και -Os flag (optimize for size). 2
migf1 Δημοσ. 23 Ιουνίου 2014 Δημοσ. 23 Ιουνίου 2014 Λοιπόν, κάτι έκανα. Μου βγήκε λίγο μεγάλο βέβαια, αλλά δεν βαριέσαι... Download: 2048.zip (κώδικας και 32μπιτο εκτελέσιμο Windows). Για όσους ασχοληθούν, ο κώδικας αποτελείται από τα εξής αρχεία: main.c (the main program) tui.c/tui.h (text-user-interface of the game) con_color.h (my preprocessor interface for console colored output) my.c/my.h (primitive x-platform console/terminal utility funcs) common.h (defs & types common to the prog and its text ui) Το main.c περιέχει το κυρίως πρόγραμμα, το tui.c περιέχει ότι σχετίζεται με το text-user-interface, και το common.h περιέχει κοινούς τους τύπους & σταθερές. Το my.c είναι μια λίγο πιο εμπλουτισμένη έκδοση από αυτήν που είχα δώσει σε προηγούμενο πόστ, για τη διαχείριση του κέρσορα, κλπ στην κονσόλα, και είναι πλήρως αυτόνομο. Θεωρητικά είναι cross-platform, αλλά το δοκίμασα μονάχα σε Windows (αν έχετε πρόβλημα σε *nix, πείτε μου και θα δω τι μπορώ να κάνω). Το con_color.h (και το συνοδευτικό con_color_private.h) είναι επίσης αυτόνομο, και ασχολείται με τα χρώματα της κονσόλας/τερματικού. Αυτό είναι δοκιμασμένα cross-platform (btw είναι καινούρια έκδοση, που δεν την έχω στο site μου). Πάνω σε αυτά τα δυο "πατάει" το tui.c, με σκοπό να τα κρύψει από το main.c. Για να κάνετε compile τον κώδικα, θέλετε C99. Βάλτε όλα αρχεία σε έναν φάκελο και με gcc δώστε: gcc -std=c99 -O2 -s my.c tui.c main.cΓια άλλους compilers, φτιάξτε ένα project, προσθέστε του τα παραπάνω αρχεία και ενεργοποιήστε την C99 υποστήριξη. Ο κώδικας έχει παρά πολλά σχόλια, αλλά δεν είμαι 100% σίγουρος πως δεν περιέχει bugs. Τον έγραψα εν μέσω αγώνων μουντιάλ, οπότε δείξτε επιείκεια Αλγοριθμικά δεν ασχολήθηκα, πέρα από το να δομήσω τον αλγόριθμο του φίλου tifosi σε μικρότερες συναρτήσεις και να τις προσαρμόσω στον δικό μου κώδικα (τώρα, αν έχω κάνει καμιά πατάτα, θα δείξει). Btw, ο κώδικας είναι τελείως free... κάντε τον ότι νομίζετε (εκτός από το να τον παρουσιάσετε σαν δικό σας ). Αν βρείτε τίποτα bugs, σφυρίξτε τα εδώ στο νήμα να τα δούμε. Have fun & keep in touch Καλά, τι ματσάρες είναι αυτές που βλέπουμε στο μουντιάλ! Μακράν το καλύτερο που θυμάμαι, κι υποτίθεται πως είμαστε ακόμα στο 1ο στάδιο, που παίζει όλος ο κατιμάς. 5
Star_Light Δημοσ. 23 Ιουνίου 2014 Δημοσ. 23 Ιουνίου 2014 Ο καλά εισαι.... Αλγερια χθές και μετα Πορτογαλία... αν και Πορτογαλια με πηρε ο ύπνος ειδα μονο 1 ημιχρονο. Στο στοιχημα πιάνω το Χ της Ελλάδας το οβερ της Κολομβιας και χάνω την Αγγλία Χθες δεν έπαιξα καν πολυ επικινδυνα παιχνιδια.
bnvdarklord Δημοσ. 23 Ιουνίου 2014 Δημοσ. 23 Ιουνίου 2014 @bnvdarklord: Δοκίμασε να βάλεις -s flag στον gcc (κάνει strip τα symbols από το εκτελέσιμο). Επιπρόσθετα, μπορείς να δοκιμάσεις και -Os flag (optimize for size). Κάτι αλλο θα "φταίει", γιατι με το -s μειώνεται ακόμα περισσότερο στα 20KB. Χρήσιμο flag, αν και φαντάζομαι θα έχει καποια drawbacks.
migf1 Δημοσ. 23 Ιουνίου 2014 Δημοσ. 23 Ιουνίου 2014 Κάτι αλλο θα "φταίει", γιατι με το -s μειώνεται ακόμα περισσότερο στα 20KB. Χρήσιμο flag, αν και φαντάζομαι θα έχει καποια drawbacks. Αυτό δεν ήταν το ζητούμενο; Να μειωθεί δηλαδή το μέγεθος του εκτελέσιμου, ή κατάλαβα λάθος;
bnvdarklord Δημοσ. 23 Ιουνίου 2014 Δημοσ. 23 Ιουνίου 2014 Αυτό δεν ήταν το ζητούμενο; Να μειωθεί δηλαδή το μέγεθος του εκτελέσιμου, ή κατάλαβα λάθος; Αυτο που αναρωτήθηκα ειναι πως γινεται το εκτελέσιμο του OP να ειναι 400KB, ενω το δικο μου, με οτι flag δοκιμασα να ειναι παντα λιγοτερο απο 100ΚΒ. Μπορεί άλλος compiler να παράγει τοσο μεγαλύτερο exe;
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα