├── README.txt ├── alldefine.h ├── datastructure.jpg ├── demo.mp4 ├── game.c ├── highscores.txt ├── makefile ├── menu.c └── savefile /README.txt: -------------------------------------------------------------------------------- 1 | Title of the project : " SK's Tetris : Sketris " 2 | 3 | Name of the student : Shadab Khan 4 | 5 | MIS ID : 111403071 6 | 7 | Description : 8 | 9 | The game of tetris is a simple game in which different types of block fall in a speed depending on the level of difficulty. The objective of the game is to create a highscore by gaining points. Game ends when the level of blocks reaches the top. Points are awarded on successful completion of a row. Completing more rows in a single turn leads to greater no. of points. While playing the game, player has live feed to the next block and the current statistics of the game. Sketris allows the user to select a difficulty level before the game starts. Sketris also gives the option of saving your highscore (provided the score is amongst the top 10 highscores saved). The player has the option to view the highscores and instructions from the menu. There is an option to pause game while playing and also save the game for future.The player can save multiple games, each having a different 'codename'. The player can load or delete saved games from the main menu or pause menu by using the 'codename'. 10 | -------------------------------------------------------------------------------- /alldefine.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * ### SK's Tetris : Sketris ### 3 | * 4 | * Copyright (C) 2015 Shadab Khan shadabk14.comp@coep.ac.in 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, version 3 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see 17 | * or write to the Free Software Foundation Inc., 51 Franklin Street, 18 | * Fifth Floor, Boston MA 02110-1301, USA. 19 | *****************************************************************************/ 20 | 21 | #define WELL_HEIGHT 22 22 | #define WELL_WIDTH 32 23 | #define NO_LEVELS 10 24 | #define NEXT_HEIGHT 10 25 | #define NEXT_WIDTH 20 26 | #define SCORE_HEIGHT 14 27 | #define SCORE_WIDTH 32 28 | 29 | #define CONTROL_UP 'i' 30 | #define CONTROL_DOWN 'k' 31 | #define CONTROL_LEFT 'j' 32 | #define CONTROL_RIGHT 'l' 33 | #define CONTROL_NEXT 's' 34 | #define CONTROL_BACK 'a' 35 | 36 | #define NITEMS 6 37 | #define NO_LEVELS 10 38 | 39 | /* Points are stored in three parts : points, lines, levels. 40 | * DOT is the structure defining the blocks : (y, x) coordinates, colour. 41 | * SC_REC is the record of a score row : player_name, POINTS, next row pointer. 42 | */ 43 | typedef struct points { 44 | unsigned int points; 45 | unsigned int lines; 46 | unsigned int level; 47 | } POINTS; 48 | 49 | 50 | typedef struct dot { 51 | unsigned char y; 52 | unsigned char x; 53 | unsigned char clr; 54 | } DOT; 55 | 56 | typedef struct sc_rec{ 57 | char pname[11]; 58 | POINTS points; 59 | struct sc_rec *next; 60 | } SC_REC; 61 | 62 | 63 | // Prototypes of all the functions used in the complete code : 64 | void print_menu(WINDOW *menuw); 65 | int menu(); 66 | char *yx2pointer(int y, int x); 67 | void update_stat(POINTS points); 68 | void update_inst(); 69 | void update_well(); 70 | void remove_row(int row); 71 | int check_row(int row); 72 | POINTS *check_lines(int start); 73 | void fix_block(int y, int x, int type,int orient); 74 | int check_pos(int y, int x, int type, int orient); 75 | void draw_block(WINDOW *win, int y, int x, int type, int orient, char delete); 76 | void update_next(int next, int del); 77 | int drop_block(int type, int level); 78 | void disp_score(char *message); 79 | int store_score(POINTS argp); 80 | void play_game(int level, int y); 81 | void init_windows(); 82 | void initialise_colors(); 83 | POINTS *loadgame(int *curr, int *next); 84 | void savegame(POINTS points, int curr, int next); 85 | -------------------------------------------------------------------------------- /datastructure.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shadabk96/tetris-minip/1fe5647c8138fe9b6c6673597e3b44b72fd859fa/datastructure.jpg -------------------------------------------------------------------------------- /demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shadabk96/tetris-minip/1fe5647c8138fe9b6c6673597e3b44b72fd859fa/demo.mp4 -------------------------------------------------------------------------------- /game.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * ### SK's Tetris : Sketris ### 3 | * 4 | * Copyright (C) 2015 Shadab Khan shadabk14.comp@coep.ac.in 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, version 3 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see 17 | * or write to the Free Software Foundation Inc., 51 Franklin Street, 18 | * Fifth Floor, Boston MA 02110-1301, USA. 19 | *****************************************************************************/ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "alldefine.h" 32 | 33 | int GAME_HEIGHT = WELL_HEIGHT + 4, GAME_WIDTH = WELL_WIDTH + NEXT_WIDTH + 4 + 20; 34 | 35 | // well_data defines the occupancy of well in terms of a character array. 36 | char **well_data; 37 | 38 | //delay[] is the time delay in microseconds depending on the level no. 39 | int delay[NO_LEVELS] = {1000000, 770000, 593000, 457000, 352000, 271000, 208000, 160000, 124000, 95000}; 40 | 41 | /* Defined all global windows : 1. Game window : gamew 42 | * 2. Well window : wellw 43 | * 3. Stats window : statw 44 | * 4. Next window : nextw 45 | * 5. Instructions window : instw 46 | * 6. Last Window : lastw 47 | * 7. Highscores Window : scorew 48 | */ 49 | WINDOW *gamew, *wellw, *statw, *nextw, *instw, *lastw, *scorew; 50 | 51 | 52 | /* block_data[types][orientations][dots] 53 | * defining the blocks : 54 | * (y, x, color no.) 55 | */ 56 | const DOT block_data[7][4][4] = 57 | { 58 | { 59 | {{2,0,1},{2,1,1},{2,2,1},{2,3,1}}, /* */ 60 | {{0,1,1},{1,1,1},{2,1,1},{3,1,1}}, /* */ 61 | {{2,0,1},{2,1,1},{2,2,1},{2,3,1}}, /* XXXX */ 62 | {{0,1,1},{1,1,1},{2,1,1},{3,1,1}} /* */ 63 | }, 64 | { 65 | {{1,1,2},{2,1,2},{1,2,2},{2,2,2}}, /* */ 66 | {{1,1,2},{2,1,2},{1,2,2},{2,2,2}}, /* XX */ 67 | {{1,1,2},{2,1,2},{1,2,2},{2,2,2}}, /* XX */ 68 | {{1,1,2},{2,1,2},{1,2,2},{2,2,2}} /* */ 69 | }, 70 | { 71 | {{1,0,3},{1,1,3},{1,2,3},{2,2,3}}, /* */ 72 | {{2,0,3},{0,1,3},{1,1,3},{2,1,3}}, /* XXX */ 73 | {{0,0,3},{1,0,3},{1,1,3},{1,2,3}}, /* X */ 74 | {{0,1,3},{1,1,3},{2,1,3},{0,2,3}} /* */ 75 | }, 76 | { 77 | {{1,0,4},{2,0,4},{1,1,4},{1,2,4}}, /* */ 78 | {{0,0,4},{0,1,4},{1,1,4},{2,1,4}}, /* XXX */ 79 | {{1,0,4},{1,1,4},{0,2,4},{1,2,4}}, /* X */ 80 | {{0,1,4},{1,1,4},{2,1,4},{2,2,4}} /* */ 81 | }, 82 | { 83 | {{1,0,5},{1,1,5},{2,1,5},{2,2,5}}, /* */ 84 | {{1,0,5},{2,0,5},{0,1,5},{1,1,5}}, /* XX */ 85 | {{1,0,5},{1,1,5},{2,1,5},{2,2,5}}, /* XX */ 86 | {{1,0,5},{2,0,5},{0,1,5},{1,1,5}} /* */ 87 | }, 88 | { 89 | {{2,0,6},{1,1,6},{2,1,6},{1,2,6}}, /* */ 90 | {{0,0,6},{1,0,6},{1,1,6},{2,1,6}}, /* XX */ 91 | {{2,0,6},{1,1,6},{2,1,6},{1,2,6}}, /* XX */ 92 | {{0,0,6},{1,0,6},{1,1,6},{2,1,6}} /* */ 93 | }, 94 | { 95 | {{1,0,7},{1,1,7},{2,1,7},{1,2,7}}, /* X */ 96 | {{1,0,7},{0,1,7},{1,1,7},{2,1,7}}, /* XXX */ 97 | {{1,0,7},{0,1,7},{1,1,7},{1,2,7}}, /* */ 98 | {{0,1,7},{1,1,7},{2,1,7},{1,2,7}} /* */ 99 | } 100 | }; 101 | 102 | 103 | // Converts (y, x) cordinates into pointer to particular location in well_data 104 | char *yx2pointer(int y, int x) { 105 | return &well_data[y][x]; 106 | } 107 | 108 | // All colour definitions are defined here : 109 | void initialise_colors() { 110 | start_color(); 111 | init_pair(9, COLOR_BLACK, COLOR_BLACK); 112 | init_pair(1, COLOR_BLACK, COLOR_RED); 113 | init_pair(11, COLOR_RED, COLOR_BLACK); 114 | init_pair(2, COLOR_BLACK, COLOR_CYAN); 115 | init_pair(12, COLOR_CYAN, COLOR_BLACK); 116 | init_pair(3, COLOR_BLACK, COLOR_BLUE); 117 | init_pair(13, COLOR_BLUE, COLOR_BLACK); 118 | init_pair(4, COLOR_BLACK, COLOR_YELLOW); 119 | init_pair(14, COLOR_YELLOW, COLOR_BLACK); 120 | init_pair(5, COLOR_BLACK, COLOR_WHITE); 121 | init_pair(15, COLOR_WHITE, COLOR_BLACK); 122 | init_pair(6, COLOR_BLACK, COLOR_GREEN); 123 | init_pair(16, COLOR_GREEN, COLOR_BLACK); 124 | init_pair(7, COLOR_BLACK, COLOR_MAGENTA); 125 | init_pair(17, COLOR_MAGENTA, COLOR_BLACK); 126 | } 127 | 128 | //Redraws stat window 129 | void update_stat(POINTS points) { 130 | box(statw, ACS_VLINE, ACS_HLINE); 131 | mvwprintw(statw, 2, 5, "Score : %d", points.points); 132 | mvwprintw(statw, 4, 5, "Lines : %d", points.lines); 133 | mvwprintw(statw, 6, 5, "Level : %d", points.level); 134 | mvwprintw(statw, 0, 6 , "# STATS #"); 135 | wrefresh(statw); 136 | } 137 | 138 | 139 | //updates the instructions window 140 | void update_inst() { 141 | mvwprintw(instw, 1, 2, "Controls :"); 142 | mvwprintw(instw, 3, 2, "Move Left -> %c", CONTROL_LEFT); 143 | mvwprintw(instw, 4, 2, "Move Right -> %c", CONTROL_RIGHT); 144 | mvwprintw(instw, 5, 2, "Move down -> %c", CONTROL_DOWN); 145 | mvwprintw(instw, 6, 2, "Rotate -> %c", CONTROL_UP); 146 | mvwprintw(instw, 7, 2, "Pause Game -> p"); 147 | mvwprintw(instw, 8, 2, "Quit game -> v"); 148 | box(instw, ACS_VLINE, ACS_HLINE); 149 | wrefresh(instw); 150 | } 151 | 152 | 153 | //Redraws well 154 | void update_well() { 155 | int y = 0, x = 0, i; 156 | for(x = 0; x < WELL_WIDTH; x++) { 157 | for(y = 0; y < WELL_HEIGHT; y++) { 158 | if(*yx2pointer(y, x) > 0) { 159 | wattrset(wellw, COLOR_PAIR(*yx2pointer(y, x))); 160 | mvwprintw(wellw, y, 2 * x, " "); 161 | } 162 | else { 163 | wattrset(wellw, COLOR_PAIR(9)); 164 | mvwprintw(wellw, y, 2 * x, " "); 165 | } 166 | } 167 | } 168 | wattroff(wellw, COLOR_PAIR(1)); 169 | box(wellw, ACS_VLINE, ACS_HLINE); 170 | wrefresh(wellw); 171 | } 172 | 173 | 174 | // Removes the completely filled row from well 175 | void remove_row(int row) { 176 | 177 | int i, j, k, x = 0, y = row; 178 | for(x = 0; x < WELL_WIDTH; x++) 179 | *yx2pointer(y, x) = 0; 180 | 181 | for(i = row - 1; i > 0; i--) { 182 | for(x = 0; x < WELL_WIDTH/2; x++) 183 | *yx2pointer(i + 1, x) = *yx2pointer(i, x); 184 | } 185 | 186 | update_well(); 187 | } 188 | 189 | 190 | // Checks if a particular row is filled 191 | int check_row(int row) { 192 | int i, j, x = 0, y = row; 193 | for(x = 1; x < WELL_WIDTH/2; x++) { 194 | if(*yx2pointer(y, x) == 0) 195 | return 0; 196 | } 197 | return 1; 198 | } 199 | 200 | 201 | /* After fixing each block, checks if any lines are complete 202 | * If lines are complete, calls remove_row 203 | * Increases score according to number of lines removed in one turn. 204 | */ 205 | POINTS *check_lines(int start) { 206 | 207 | int y, count_row = 0; 208 | POINTS *temp = (POINTS *)malloc(sizeof(POINTS)); 209 | temp->points = 0; 210 | temp->lines = 0; 211 | 212 | for (y = start; y < start + 4; y++) 213 | if(check_row(y)) { 214 | remove_row(y); 215 | count_row++; 216 | } 217 | switch(count_row) { 218 | 219 | case 1 : temp->points = 10; 220 | temp->lines = 1; 221 | break; 222 | 223 | case 2 : temp->points = 25; 224 | temp->lines = 2; 225 | break; 226 | 227 | case 3 : temp->points = 40; 228 | temp->lines = 3; 229 | break; 230 | 231 | case 4 : temp->points = 60; 232 | temp->lines = 4; 233 | break; 234 | 235 | default : break; 236 | } 237 | return temp; 238 | } 239 | 240 | 241 | // Fixes the block in a particular location in well 242 | void fix_block(int y, int x, int type,int orient) { 243 | int i; 244 | DOT dot; 245 | for (i = 0; i < 4; i++) { 246 | dot = block_data[type][orient][i]; 247 | *yx2pointer(y + dot.y, x + dot.x) = dot.clr; 248 | } 249 | } 250 | 251 | 252 | //checks if the block can be moved to the next location 253 | int check_pos(int y, int x, int type, int orient) { 254 | int i; 255 | DOT dot; 256 | for(i = 0; i < 4; i++) { 257 | dot = block_data[type][orient][i]; 258 | if ((y + dot.y > WELL_HEIGHT - 1) || 259 | (x + dot.x < 1) || 260 | (x + dot.x > WELL_WIDTH/2 - 1) || 261 | ((*yx2pointer(y + dot.y, x + dot.x) > 0)) 262 | ) 263 | return 0; 264 | } 265 | return 1; 266 | } 267 | 268 | 269 | // Draws or erases the block depending on the delete value 270 | void draw_block(WINDOW *win, int y, int x, int type, int orient, char delete) { 271 | int i; 272 | DOT dot; 273 | 274 | for (i = 0; i < 4; i++) { 275 | dot = block_data[type][orient][i]; 276 | wattron(win, COLOR_PAIR(delete ? 9 : dot.clr)); 277 | mvwprintw(win, y + dot.y, 2*(x + dot.x), " "); 278 | } 279 | if (delete == 0) 280 | wrefresh(win); 281 | wattroff(win, COLOR_PAIR(delete ? 9 : 1)); 282 | box(win, ACS_VLINE, ACS_HLINE); 283 | wrefresh(win); 284 | } 285 | 286 | //Redraws the window showing next block 287 | void update_next(int next, int del) { 288 | mvwprintw(nextw, 0, 4, "NEXT BLOCK"); 289 | if(del == 1) 290 | draw_block(nextw, 3, 3, next, 0, 1); 291 | if(del == 0) 292 | draw_block(nextw, 3, 3, next, 0, 0); 293 | box(nextw, ACS_VLINE, ACS_HLINE); 294 | mvwprintw(nextw, 0, 3 , "# NEXT BLOCK #"); 295 | wrefresh(nextw); 296 | 297 | } 298 | 299 | // Saves game to savefile.csp 300 | void savegame(POINTS points, int curr, int next) { 301 | FILE *fp; 302 | int i, j; 303 | char ch; 304 | 305 | //Section for taking input. 306 | //-------------------------------------------------------------------------------------------------- 307 | scorew = newwin(GAME_HEIGHT - 2, GAME_WIDTH, 0, 0); 308 | box(scorew, ACS_VLINE, ACS_HLINE); 309 | wrefresh(scorew); 310 | 311 | mvwprintw(scorew, 10, 20,"Please enter the savefile codename : ["); 312 | mvwprintw(scorew, 10, 20 + 10 + strlen("Please enter the savefile codename : ["),"]"); 313 | mvwprintw(scorew, 13, 30,"Press '+' to continue"); 314 | mvwprintw(scorew, 14, 30,"Press '-' for backspace"); 315 | mvwprintw(scorew, 15, 30,"Press '/' to cancel"); 316 | wrefresh(scorew); 317 | nodelay(stdscr, FALSE); 318 | int letter_count = 0; 319 | char tempname[11]; 320 | for(i = 0; i < 10; i++) 321 | tempname[i] = ' '; 322 | tempname[10] = '\0'; 323 | do { 324 | ch = wgetch(scorew); 325 | tempname[letter_count] = ch; 326 | if(ch == '-') { 327 | tempname[letter_count ] = ' '; 328 | (letter_count > 0 ) ? ( letter_count = letter_count - 2) : letter_count; 329 | tempname[letter_count + 1] = ' '; 330 | } 331 | if(ch == '/') 332 | return; 333 | letter_count++; 334 | wattrset(scorew, COLOR_PAIR(14)); 335 | mvwprintw(scorew, 10, 21 + strlen("Please enter the savefile codename : ["),"%s", tempname); 336 | wattroff(scorew, COLOR_PAIR(14)); 337 | mvwprintw(scorew, 10, 20 + 10 + strlen("Please enter the savefile codename : ["),"]"); 338 | wrefresh(scorew); 339 | } while((ch != '+') && (letter_count != 10)); 340 | if((ch == '+') || (ch == '#')) 341 | tempname[letter_count - 1] = ' '; 342 | if(ch == '#') { 343 | int status; 344 | status = remove(tempname); 345 | if(status == 0) 346 | mvwprintw(scorew, 18, 30,"File deleted successfully"); 347 | else 348 | mvwprintw(scorew, 16, 30,"File doesn't exist"); 349 | } 350 | nodelay(stdscr, TRUE); 351 | wclear(scorew); 352 | wrefresh(scorew); 353 | update_inst(); 354 | //-------------------------------------------------------------------------------------------------- 355 | 356 | 357 | fp = fopen(tempname, "w"); 358 | for(i = 0; i < WELL_WIDTH; i++) 359 | for(j = 0; j < WELL_HEIGHT; j++) { 360 | ch = well_data[i][j]; 361 | fputc(ch, fp); 362 | } 363 | ch = '\n'; 364 | fputc(ch, fp); 365 | fprintf(fp, "%d\n", points.points); 366 | fprintf(fp, "%d\n", points.lines); 367 | fprintf(fp, "%d\n", points.level); 368 | fprintf(fp, "%d\n", curr); 369 | fprintf(fp, "%d\n", next); 370 | fclose(fp); 371 | } 372 | 373 | // Loads game from savefile.csp 374 | POINTS *loadgame(int *curr, int *next) { 375 | FILE * fp; 376 | int i, j; 377 | char ch; 378 | POINTS *temp; 379 | temp = (POINTS *)malloc(sizeof(POINTS)); 380 | 381 | //Section for taking input. 382 | //-------------------------------------------------------------------------------------------------- 383 | scorew = newwin(GAME_HEIGHT - 2, GAME_WIDTH, 0, 0); 384 | box(scorew, ACS_VLINE, ACS_HLINE); 385 | wrefresh(scorew); 386 | 387 | mvwprintw(scorew, 10, 20,"Please enter the savefile codename : ["); 388 | mvwprintw(scorew, 10, 20 + 10 + strlen("Please enter the savefile codename : ["),"]"); 389 | mvwprintw(scorew, 13, 30,"Press '+' to continue"); 390 | mvwprintw(scorew, 14, 30,"Press '-' for backspace"); 391 | mvwprintw(scorew, 15, 30,"Press '#' to delete savefile"); 392 | mvwprintw(scorew, 16, 30,"Press '/' to cancel"); 393 | wrefresh(scorew); 394 | nodelay(stdscr, FALSE); 395 | int letter_count = 0; 396 | char tempname[11]; 397 | for(i = 0; i < 10; i++) 398 | tempname[i] = ' '; 399 | tempname[10] = '\0'; 400 | do { 401 | ch = wgetch(scorew); 402 | tempname[letter_count] = ch; 403 | if(ch == '-') { 404 | tempname[letter_count ] = ' '; 405 | (letter_count > 0 ) ? ( letter_count = letter_count - 2) : letter_count; 406 | tempname[letter_count + 1] = ' '; 407 | } 408 | letter_count++; 409 | if(ch == '#') 410 | break; 411 | if(ch == '/') { 412 | temp->points = -2; 413 | return temp; 414 | } 415 | wattrset(scorew, COLOR_PAIR(14)); 416 | mvwprintw(scorew, 10, 21 + strlen("Please enter the savefile codename : ["),"%s", tempname); 417 | wattroff(scorew, COLOR_PAIR(14)); 418 | mvwprintw(scorew, 10, 20 + 10 + strlen("Please enter the savefile codename : ["),"]"); 419 | wrefresh(scorew); 420 | } while((ch != '+') && (letter_count != 10)); 421 | if((ch == '+') || (ch == '#')) 422 | tempname[letter_count - 1] = ' '; 423 | if(ch == '#') { 424 | int status; 425 | status = remove(tempname); 426 | if(status == 0) 427 | mvwprintw(scorew, 18, 30,"File deleted successfully"); 428 | else 429 | mvwprintw(scorew, 18, 30,"File doesn't exist"); 430 | ch = wgetch(scorew); 431 | nodelay(stdscr, TRUE); 432 | temp->points = -2; 433 | return temp; 434 | } 435 | nodelay(stdscr, TRUE); 436 | wclear(scorew); 437 | wrefresh(scorew); 438 | update_inst(); 439 | //-------------------------------------------------------------------------------------------------- 440 | 441 | fp = fopen(tempname, "r"); 442 | if(fp == NULL) 443 | temp->points = -1; 444 | else { 445 | for(i = 0; i < WELL_WIDTH; i++) 446 | for(j = 0; j < WELL_HEIGHT; j++) { 447 | well_data[i][j] = fgetc(fp); 448 | } 449 | fgetc(fp); 450 | fscanf(fp, "%d%d%d%d%d", &(temp->points), &(temp->lines), &(temp->level), curr, next); 451 | } 452 | return temp; 453 | } 454 | 455 | 456 | 457 | /* Drops block till it reaches either well floor or another line 458 | * Uses time variables 459 | * Controls the block while it falls 460 | */ 461 | int drop_block(int type, int level) { 462 | int mid = WELL_WIDTH / 2 - 2; 463 | int y = 0; 464 | int x = mid/2; 465 | int orient = 0; 466 | int pause = 0; 467 | char ch, dh; 468 | fd_set t1, t2; 469 | struct timeval timeout; 470 | int sel_ret; 471 | if (0 == check_pos(y + 1, x, type, orient)) //check if game over 472 | return -1; 473 | if (0 == check_pos(y + 1, x + 1, type, orient)) //check if game over 474 | return -1; 475 | if (0 == check_pos(y + 1, x + 2, type, orient)) //check if game over 476 | return -1; 477 | if (0 == check_pos(y + 1, x + 3, type, orient)) //check if game over 478 | return -1; 479 | 480 | timeout.tv_sec = 0; 481 | timeout.tv_usec = delay[level]; 482 | 483 | FD_ZERO(&t1); //initialise 484 | FD_SET(0, &t1); 485 | 486 | draw_block(wellw, y, x, type, orient, 0); 487 | 488 | while(1) { 489 | t2 = t1; 490 | sel_ret = select(FD_SETSIZE, &t2, (fd_set *) 0, (fd_set *) 0, &timeout); 491 | ch = getch(); 492 | switch (ch) { 493 | 494 | case CONTROL_LEFT: //-------------------------------move left 495 | if(check_pos(y, x - 1, type, orient)) { 496 | draw_block(wellw, y, x, type, orient, 1); 497 | draw_block(wellw, y, --x, type, orient, 0); 498 | } 499 | break; 500 | 501 | case CONTROL_RIGHT: //-------------------------------move right 502 | if(check_pos(y, x + 1, type, orient)) { 503 | draw_block(wellw, y, x, type, orient, 1); 504 | draw_block(wellw, y, ++x, type, orient, 0); 505 | } 506 | break; 507 | 508 | case CONTROL_UP: //-----------------------------------rotate 509 | if (check_pos(y, x, type, orient + 1 == 4 ? 0 : orient + 1)) { 510 | draw_block(wellw, y, x, type, orient, 1); 511 | ++orient == 4 ? orient = 0 : 0; 512 | draw_block(wellw, y, x, type, orient, 0); 513 | } 514 | break; 515 | 516 | case CONTROL_DOWN: //------------------------------------------------------------------------move down 517 | sel_ret = 0; 518 | break; 519 | 520 | case 'p': //----------------------------------------------------------------------------pause 521 | { 522 | lastw = newwin(10, 20, WELL_HEIGHT - 10, WELL_WIDTH + NEXT_WIDTH + 4); 523 | wattrset(lastw, COLOR_PAIR(2)); 524 | box(lastw, ' ', ' '); 525 | wattroff(lastw, COLOR_PAIR(2)); 526 | mvwprintw(lastw, 1, 2, ".. Game Paused .."); 527 | mvwprintw(lastw, 3, 3, "Press 'p'"); 528 | mvwprintw(lastw, 4, 3, "to continue"); 529 | mvwprintw(lastw, 5, 3, "Press 's'"); 530 | mvwprintw(lastw, 6, 3, "to save game"); 531 | mvwprintw(lastw, 7, 3, "Press 'l'"); 532 | mvwprintw(lastw, 8, 3, "to load game"); 533 | wrefresh(lastw); 534 | dh = wgetch(wellw); 535 | if(dh == 's') { 536 | delwin(lastw); 537 | return -2; 538 | } 539 | if(dh == 'l') { 540 | return -3; 541 | } 542 | } 543 | while(dh != 'p'); 544 | delwin(lastw); 545 | update_inst(); 546 | break; 547 | 548 | case 'v': //-----------------------------------------------------------------------------quit 549 | return -1; 550 | } 551 | 552 | if(sel_ret == 0) { 553 | if(check_pos(y + 1, x, type, orient)) { //----------------------------------moves block down 554 | draw_block(wellw, y, x, type, orient, 1); 555 | draw_block(wellw, ++y, x, type, orient, 0); 556 | } 557 | else { //--------------------------------fix block in place 558 | fix_block(y, x, type, orient); 559 | return y; 560 | } 561 | timeout.tv_sec = 0; 562 | timeout.tv_usec = delay[level]; 563 | } 564 | } 565 | } 566 | 567 | 568 | /* Displays the score from highscores.txt file 569 | * Can be called anytime. 570 | */ 571 | void disp_score(char *message) { 572 | nodelay(stdscr, FALSE); 573 | char ch, str[15]; 574 | wclear(gamew); 575 | POINTS points; 576 | scorew = newwin(GAME_HEIGHT - 2, GAME_WIDTH, 0, 0); 577 | box(scorew, ACS_VLINE, ACS_HLINE); 578 | wrefresh(scorew); 579 | 580 | 581 | if(message != NULL) { 582 | wattrset(scorew, COLOR_PAIR(1)); 583 | mvwprintw(scorew, 17 , 19, "## %s ##", message); 584 | wattroff(scorew, COLOR_PAIR(1)); 585 | } 586 | FILE *fp; 587 | fp = fopen("highscores.txt", "r"); 588 | if(fp == NULL) { 589 | mvwprintw(scorew, 10, 10, "Highscores file not found."); 590 | wrefresh(scorew); 591 | ch = getch(); 592 | return; 593 | } 594 | 595 | wattrset(scorew, COLOR_PAIR(14)); 596 | mvwprintw(scorew, 2, 23, "## Highscores ##"); 597 | mvwprintw(scorew, 19, 17, "## Press any key to exit ##"); 598 | wattroff(scorew, COLOR_PAIR(14)); 599 | mvwprintw(scorew, 4, 10, "Player Name"); 600 | mvwprintw(scorew, 4, 27, "Points"); 601 | mvwprintw(scorew, 4, 37, "Lines"); 602 | mvwprintw(scorew, 4, 47, "Level"); 603 | mvwprintw(scorew, 6, 7, "1."); 604 | 605 | int i = 10, j = 6, rank = 2; 606 | while((ch = fgetc(fp)) != EOF) { 607 | if(ch == '\t') { 608 | i = (((i + 10) / 10 ) * 10); 609 | continue; 610 | } 611 | if(ch == '\n') { 612 | i = 10; 613 | j++; 614 | mvwprintw(scorew, j, 7, "%d.", rank++); 615 | continue; 616 | } 617 | mvwprintw(scorew, j, i, "%c", ch); 618 | i++; 619 | wrefresh(scorew); 620 | } 621 | ch = getch(); 622 | nodelay(stdscr, TRUE); 623 | } 624 | 625 | 626 | /* Reads score, compares arg score with stored scores 627 | * Returns 1, if arg score can be stored and stores it 628 | * Return 0, if arg score is too low 629 | */ 630 | int store_score(POINTS argp) { 631 | 632 | char ch, tempno[10]; 633 | int i, rows = 0; 634 | SC_REC *score, *head, *prev; 635 | head = NULL; 636 | prev = NULL; 637 | 638 | //----------------------------------------------------------------------reads from stored highscore file. 639 | FILE *fp; 640 | fp = fopen("highscores.txt", "r"); 641 | if(fp != NULL) { 642 | while((ch = fgetc(fp)) != EOF) { 643 | score = (SC_REC *)malloc(sizeof(SC_REC)); 644 | score->next = NULL; 645 | if(head == NULL) 646 | head = score; 647 | if(prev != NULL) 648 | prev->next = score; 649 | i = 0; 650 | while(ch != '\t') { 651 | score->pname[i] = ch; 652 | ch = fgetc(fp); 653 | i++; 654 | } 655 | 656 | (score->pname)[10] = '\0'; 657 | i = 0; 658 | ch = fgetc(fp); 659 | while(ch != '\t') { 660 | tempno[i++] = ch; 661 | ch = fgetc(fp); 662 | } 663 | tempno[i] = '\0'; 664 | (score->points).points = atoi(tempno); 665 | i = 0; 666 | ch = fgetc(fp); 667 | while(ch != '\t') { 668 | tempno[i++] = ch; 669 | ch = fgetc(fp); 670 | } 671 | tempno[i] = '\0'; 672 | (score->points).lines = atoi(tempno); 673 | i = 0; 674 | ch = fgetc(fp); 675 | while((ch != '\n') && (ch != EOF)) { 676 | tempno[i++] = ch; 677 | ch = fgetc(fp); 678 | } 679 | tempno[i] = '\0'; 680 | (score->points).level = atoi(tempno); 681 | prev = score; 682 | rows++; 683 | } 684 | fclose(fp); 685 | } 686 | 687 | //----------------------------------------------------------------------checks if current is in top 10. 688 | rows = 0; 689 | SC_REC *temp, new; 690 | temp = head; 691 | while(temp) { 692 | if(temp->points.points > argp.points) { 693 | prev = temp; 694 | rows++; 695 | } 696 | temp = temp->next; 697 | } 698 | if(rows == 10) 699 | return 0; 700 | 701 | //----------------------------------------------------------------------asks user for name. 702 | scorew = newwin(GAME_HEIGHT - 2, GAME_WIDTH, 0, 0); 703 | box(scorew, ACS_VLINE, ACS_HLINE); 704 | wrefresh(scorew); 705 | 706 | mvwprintw(scorew, 10, 20,"Please enter your name : ["); 707 | mvwprintw(scorew, 10, 20 + 10 + strlen("Please enter your name : ["),"]"); 708 | mvwprintw(scorew, 13, 30,"Press '+' to continue"); 709 | mvwprintw(scorew, 14, 30,"Press '-' for backspace"); 710 | mvwprintw(scorew, 15, 30,"Press '/' to cancel"); 711 | wrefresh(scorew); 712 | nodelay(stdscr, FALSE); 713 | int letter_count = 0; 714 | char tempname[11]; 715 | for(i = 0; i < 10; i++) 716 | tempname[i] = ' '; 717 | tempname[10] = '\0'; 718 | do { 719 | ch = wgetch(scorew); 720 | tempname[letter_count] = ch; 721 | if(ch == '-') { 722 | tempname[letter_count ] = ' '; 723 | (letter_count > 0 ) ? ( letter_count = letter_count - 2) : letter_count; 724 | tempname[letter_count + 1] = ' '; 725 | } 726 | if(ch == '/') 727 | return 1; 728 | letter_count++; 729 | wattrset(scorew, COLOR_PAIR(14)); 730 | mvwprintw(scorew, 10, 21 + strlen("Please enter your name : ["),"%s", tempname); 731 | wattroff(scorew, COLOR_PAIR(14)); 732 | mvwprintw(scorew, 10, 20 + 10 + strlen("Please enter your name : ["),"]"); 733 | wrefresh(scorew); 734 | } while((ch != '+') && (letter_count != 10)); 735 | if(ch == '+') 736 | tempname[letter_count - 1] = ' '; 737 | strcpy(new.pname, tempname); 738 | 739 | new.points.points = argp.points; 740 | new.points.lines = argp.lines; 741 | new.points.level = argp.level; 742 | 743 | //----------------------------------------------------------adds current score to the stored table of scores. 744 | if(rows == 0) { 745 | new.next = head; 746 | head = &new; 747 | } 748 | else { 749 | new.next = prev->next; 750 | prev->next = &new; 751 | } 752 | 753 | rows = 0; 754 | temp = head; 755 | while(temp->next) { 756 | prev = temp; 757 | temp = temp->next; 758 | rows++; 759 | } 760 | if(rows == 10) { 761 | prev->next = NULL; 762 | free(temp); 763 | } 764 | 765 | //----------------------------------------------------------------------writes the table to highscores.txt file 766 | temp = head; 767 | fp = fopen("highscores.txt", "wr+"); 768 | while(temp) { 769 | fprintf(fp, "%s", temp->pname); 770 | fprintf(fp, "\t"); 771 | fprintf(fp, "%d", temp->points.points); 772 | fprintf(fp, "\t"); 773 | fprintf(fp, "%d", temp->points.lines); 774 | fprintf(fp, "\t"); 775 | fprintf(fp, "%d", temp->points.level); 776 | fprintf(fp, "\n"); 777 | 778 | temp = temp->next; 779 | } 780 | fclose(fp); 781 | 782 | return 1; 783 | } 784 | 785 | 786 | /* Actual loop of the game. 787 | * initialises well_data, calls drop_block, sets score 788 | * 789 | */ 790 | void play_game(int level, int y) { 791 | 792 | POINTS points, tpts, *temp; 793 | int i, j, curr, next, count_lines_rem; 794 | char ch; 795 | 796 | well_data = (char **)malloc((sizeof(char *)) * WELL_WIDTH); 797 | for(i = 0; i < WELL_WIDTH; i++) { 798 | well_data[i] = (char *)malloc((sizeof(char)) * WELL_HEIGHT); 799 | for(j = 0; j < WELL_HEIGHT; j++) 800 | well_data[i][j] = 0; 801 | } 802 | points.points = 0; 803 | points.lines = 0; 804 | points.level = level; 805 | 806 | temp = &tpts; 807 | count_lines_rem = level * 3; 808 | 809 | curr = rand() % 7; 810 | 811 | update_stat(points); 812 | 813 | while(y > 0 || y == -3) { 814 | temp->points = 0; 815 | temp->lines = 0; 816 | update_next(curr, 1); 817 | next = rand() % 7; 818 | if(y == -3) { 819 | temp = loadgame(&curr, &next); 820 | if((temp->points == -1) || (temp->points == -2)) { 821 | char *message; 822 | message = (char *)malloc(strlen("No Savefile Found") + 1 ); 823 | strcpy(message, "No Savefile Found"); 824 | if(temp->points == -2) 825 | message = NULL; 826 | disp_score(message); 827 | delwin(wellw); 828 | endwin(); 829 | return; 830 | } 831 | update_well(); 832 | points.points = temp->points; 833 | points.lines = temp->lines; 834 | points.level = temp->level; 835 | update_stat(points); 836 | } 837 | update_next(next, 0); 838 | y = drop_block(curr, points.level); 839 | 840 | if(y == -2) { 841 | savegame(points, curr, next); 842 | return; 843 | } 844 | 845 | if(y > 0) 846 | temp = check_lines(y); 847 | if(temp->points > 0) { 848 | points.points = points.points + temp->points; 849 | points.lines = points.lines + temp->lines; 850 | count_lines_rem++; 851 | points.level = (count_lines_rem / 3); 852 | } 853 | update_stat(points); 854 | curr = next; 855 | update_inst(); 856 | 857 | if(y == -1) { 858 | lastw = newwin(10, 20, 8, 35); 859 | wattrset(lastw, COLOR_PAIR(4)); 860 | box(lastw, ' ', ' '); 861 | wattroff(lastw, COLOR_PAIR(4)); 862 | mvwprintw(lastw, 1, 2, "# Game Over #"); 863 | mvwprintw(lastw, 2, 2, "<- Your Score ->"); 864 | mvwprintw(lastw, 3, 4, "Score : %d", points.points); 865 | mvwprintw(lastw, 4, 4, "Lines : %d", points.lines); 866 | mvwprintw(lastw, 5, 4, "Level : %d", points.level); 867 | mvwprintw(lastw, 7, 2, "Save Score ? y/n"); 868 | wrefresh(lastw); 869 | nodelay(stdscr, FALSE); 870 | ch = getch(); 871 | if(ch == 'n') { 872 | disp_score(NULL); 873 | delwin(wellw); 874 | endwin(); 875 | } 876 | else if(ch == 'y') { 877 | if(store_score(points)) 878 | disp_score(NULL); 879 | else { 880 | wattrset(lastw, COLOR_PAIR(15)); 881 | mvwprintw(lastw, 7, 1, "Your score is not"); 882 | mvwprintw(lastw, 8, 2, "in the Top 10"); 883 | wattroff(lastw, COLOR_PAIR(15)); 884 | wrefresh(lastw); 885 | ch = getch(); 886 | disp_score(NULL); 887 | } 888 | } 889 | } 890 | } 891 | return; 892 | } 893 | 894 | 895 | // Initiliases the windows for the first time : 896 | void init_windows() { 897 | POINTS points; 898 | points.points = 0; 899 | points.lines = 0; 900 | points.level = 0; 901 | int STAT_HEIGHT = WELL_HEIGHT / 2; 902 | gamew = newwin( GAME_HEIGHT, GAME_WIDTH, 0, 0); 903 | wellw = newwin( WELL_HEIGHT + 1, WELL_WIDTH + 2, 1, 1 ); 904 | statw = newwin( STAT_HEIGHT, NEXT_WIDTH, NEXT_HEIGHT + 2, WELL_WIDTH + 3 ); 905 | nextw = newwin( NEXT_HEIGHT, NEXT_WIDTH, 2, WELL_WIDTH + 3 ); 906 | instw = newwin( WELL_HEIGHT + 1, 20, 1, WELL_WIDTH + NEXT_WIDTH + 4 ); 907 | update_stat(points); 908 | update_next(1, 1); 909 | update_inst(); 910 | box(statw, ACS_VLINE, ACS_HLINE); 911 | wrefresh( wellw ); 912 | wrefresh( statw ); 913 | } 914 | 915 | // The main function : 916 | int main() { 917 | int ch, level, y; 918 | keypad(gamew, TRUE); 919 | initscr(); 920 | while(1) { 921 | y = 1; 922 | initialise_colors(); 923 | bkgd(COLOR_PAIR(9)); 924 | refresh(); 925 | int play = menu(); 926 | if(play == -1) {delwin( gamew ); 927 | endwin(); 928 | return 0;} 929 | if(play == -2) 930 | continue; 931 | init_windows(); 932 | if(play == -3) { 933 | y = -3; 934 | level = 0; 935 | } 936 | else 937 | level = play; 938 | nodelay(stdscr, TRUE); 939 | play_game(level, y); 940 | 941 | clear(); 942 | refresh(); 943 | } 944 | delwin( gamew ); 945 | endwin(); 946 | } 947 | -------------------------------------------------------------------------------- /highscores.txt: -------------------------------------------------------------------------------- 1 | ---------- 0 0 0 2 | ---------- 0 0 0 3 | ---------- 0 0 0 4 | ---------- 0 0 0 5 | ---------- 0 0 0 6 | ---------- 0 0 0 7 | ---------- 0 0 0 8 | ---------- 0 0 0 9 | ---------- 0 0 0 10 | ---------- 0 0 0 11 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | project : game.o menu.o 2 | cc game.o menu.o -lncurses -o project 3 | game.o : game.c 4 | cc -c game.c 5 | menu.o : menu.c 6 | cc -c menu.c 7 | clean : 8 | rm -f *.o project 9 | -------------------------------------------------------------------------------- /menu.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * ### SK's Tetris : Sketris ### 3 | * 4 | * Copyright (C) 2015 Shadab Khan shadabk14.comp@coep.ac.in 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, version 3 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see 17 | * or write to the Free Software Foundation Inc., 51 Franklin Street, 18 | * Fifth Floor, Boston MA 02110-1301, USA. 19 | *****************************************************************************/ 20 | 21 | #include 22 | #include "alldefine.h" 23 | 24 | WINDOW *menuw, *miw, *titlew; 25 | 26 | void print_menu(WINDOW *menuw) { 27 | 28 | wattrset(titlew, COLOR_PAIR(6)); 29 | box( titlew, ACS_BULLET, ACS_BULLET ); // sets default borders for the window 30 | mvwprintw(titlew, 1, 1, " SK's Tetris : Sketris "); 31 | wattroff(titlew, COLOR_PAIR(6)); 32 | wrefresh(titlew); 33 | 34 | int i; 35 | char item[20]; 36 | char list[NITEMS][20] = { "New Game", 37 | "Load/Delete Game", 38 | "Instructions", 39 | "High Scores", 40 | "About Developers", 41 | "Exit" }; 42 | box( menuw, ACS_VLINE, ACS_HLINE ); // sets default borders for the window 43 | 44 | // now print all the menu items and highlight the first one 45 | for( i = 0; i < NITEMS; i++ ) { 46 | sprintf(item, "%s", list[i]); 47 | mvwprintw( menuw, i+1, 2, "%s", item ); 48 | } 49 | 50 | mvwprintw( menuw, 11, 2, "'%c' -> Up", CONTROL_UP); 51 | mvwprintw( menuw, 12, 2, "'%c' -> Down", CONTROL_DOWN); 52 | mvwprintw( menuw, 13, 2, "Press '%c' to select ",CONTROL_NEXT ); 53 | wrefresh( menuw ); // update the terminal screen 54 | } 55 | 56 | // Prints the main menu of the game 57 | 58 | int menu() { 59 | char list[NITEMS][20] = { "New Game", 60 | "Load/Delete Game", 61 | "Instructions", 62 | "High Scores", 63 | "About Developers", 64 | "Exit" }; 65 | char item[20]; 66 | int ch, dh, i = 0, width = 7; 67 | 68 | initscr(); // initialize Ncurses 69 | menuw = newwin( 15, 25, 4, 1 ); // create a new window 70 | box( menuw, ACS_VLINE, ACS_HLINE ); // sets default borders for the window 71 | 72 | titlew = newwin( 3, 25, 1, 1); 73 | wattrset(titlew, COLOR_PAIR(6)); 74 | box( titlew, ACS_BULLET, ACS_BULLET ); // sets default borders for the window 75 | mvwprintw(titlew, 1, 1, " SK's Tetris : Sketris "); 76 | wattroff(titlew, COLOR_PAIR(6)); 77 | wrefresh(titlew); 78 | 79 | // now print all the menu items and highlight the first one 80 | for( i = 0; i < NITEMS; i++ ) { 81 | if( i == 0 ) 82 | wattron( menuw, A_STANDOUT ); // highlights the first item. 83 | else 84 | wattroff( menuw, A_STANDOUT ); 85 | sprintf(item, "%s", list[i]); 86 | mvwprintw( menuw, i+1, 2, "%s", item ); 87 | } 88 | 89 | mvwprintw( menuw, 11, 2, "'%c' -> Up", CONTROL_UP); 90 | mvwprintw( menuw, 12, 2, "'%c' -> Down", CONTROL_DOWN); 91 | mvwprintw( menuw, 13, 2, "Press '%c' to select ", CONTROL_NEXT); 92 | wrefresh( menuw ); // update the terminal screen 93 | 94 | i = 0; 95 | noecho(); // disable echoing of characters on the screen 96 | keypad( menuw, TRUE ); // enable keyboard input for the window. 97 | curs_set( 0 ); // hide the default screen cursor. 98 | 99 | // get the input 100 | while(ch = wgetch(menuw)){ 101 | 102 | // right pad with spaces to make the items appear with even width. 103 | sprintf(item, "%s", list[i]); 104 | mvwprintw( menuw, i+1, 2, "%s", item ); 105 | // use a variable to increment or decrement the value based on the input. 106 | switch( ch ) { 107 | case CONTROL_UP: 108 | i--; 109 | i = ( i < 0 ) ? (NITEMS - 1) : i; 110 | break; 111 | case CONTROL_DOWN: 112 | i++; 113 | i = ( i > (NITEMS - 1) ) ? 0 : i; 114 | break; 115 | case CONTROL_NEXT : if(i == 0) { 116 | int lvl = 0; 117 | miw = newwin( 10, 45, 4, 30 ); 118 | wrefresh(miw); 119 | miw = newwin( 10, 25, 4, 30 ); 120 | mvwprintw(miw, 1, 2, "Select Level :"); 121 | mvwprintw(miw, 5, 2, "'%c' -> level up", CONTROL_UP); 122 | mvwprintw(miw, 6, 2, "'%c' -> level down", CONTROL_DOWN); 123 | mvwprintw(miw, 7, 2, "'%c' -> select", CONTROL_NEXT); 124 | mvwprintw(miw, 8, 2, "'%c' -> go back", CONTROL_BACK); 125 | box(miw, ACS_VLINE, ACS_HLINE); 126 | wrefresh(miw); 127 | while( dh = wgetch(miw)) { 128 | switch( dh ) { 129 | case CONTROL_DOWN : lvl--; 130 | lvl = (lvl < 0) ? (NO_LEVELS - 1) : lvl; 131 | break; 132 | case CONTROL_UP : lvl++; 133 | lvl = ( lvl > (NO_LEVELS - 1) ) ? 0 : lvl; 134 | break; 135 | case CONTROL_BACK : 136 | return -2; 137 | case CONTROL_NEXT : 138 | return lvl; 139 | } 140 | mvwprintw(miw, 2, 5, " %d ", lvl); 141 | wrefresh(miw); 142 | } 143 | } 144 | 145 | if(i == 1) { 146 | return -3; 147 | } 148 | 149 | if(i == 2) { 150 | miw = newwin( 10, 45, 4, 30 ); 151 | mvwprintw(miw, 1, 2, "Controls :"); 152 | mvwprintw(miw, 3, 2, "Move Left -> j"); 153 | mvwprintw(miw, 4, 2, "Move Right -> l"); 154 | mvwprintw(miw, 5, 2, "Move down -> k"); 155 | mvwprintw(miw, 6, 2, "Rotate -> i"); 156 | mvwprintw(miw, 7, 2, "Pause Game -> p"); 157 | mvwprintw(miw, 8, 2, "Quit game -> v"); 158 | wrefresh(miw); 159 | } 160 | 161 | if(i == 3) { 162 | disp_score(NULL); 163 | clear(); 164 | refresh(); 165 | print_menu(menuw); 166 | } 167 | 168 | if(i == 4) { 169 | miw = newwin( 10, 45, 4, 30 ); 170 | wclear(miw); 171 | mvwprintw(miw, 2, 2, "Game Developer :"); 172 | mvwprintw(miw, 4, 2, "Contact info :"); 173 | mvwprintw(miw, 6, 2, "For Source code visit :"); 174 | wattrset(miw, COLOR_PAIR(12)); 175 | mvwprintw(miw, 3, 2, " \"Shadab Khan\""); 176 | mvwprintw(miw, 5, 2, " \"shadabk14.comp@coep.ac.in\""); 177 | mvwprintw(miw, 7, 2, " \"https://github.com/shadabk/tetris-minip\""); 178 | wattroff(miw, COLOR_PAIR(12)); 179 | wrefresh(miw); 180 | } 181 | 182 | if(i == 5) { 183 | delwin( menuw ); 184 | endwin(); 185 | return -1; 186 | } 187 | break; 188 | } 189 | // now highlight the next item in the list. 190 | wattron( menuw, A_STANDOUT ); 191 | sprintf(item, "%s", list[i]); 192 | mvwprintw( menuw, i+1, 2, "%s", item); 193 | wattroff( menuw, A_STANDOUT ); 194 | } 195 | 196 | delwin( menuw ); 197 | endwin(); 198 | } 199 | -------------------------------------------------------------------------------- /savefile : -------------------------------------------------------------------------------- 1 |  2 | 10 3 | 1 4 | 4 5 | 2 6 | 1 7 | --------------------------------------------------------------------------------