/* _ (_ _)UDOKU Authored by abakh No rights are reserved and this software comes with no warranties of any kind to the extent permitted by law. compile with -lncurses -lm NOTE: This program is only made for entertainment porpuses. The puzzles are generated by randomly clearing tiles on the table and are guaranteed to have a solution , but are not guaranteed to have only one unique solution. */ #include #include #include #include //to seed random #include #include #include #include "config.h" typedef signed char byte; byte _wait=0, waitcycles=0;//apparently 'wait' conflicts with a variable in a library macOS includes by default byte py,px; byte diff; unsigned int filled; chtype colors[6]={0}; #if defined Plan9 //the Plan9 compiler can not handle VLAs #define size 3 #define s 9 // I hope this is approximately right int round(float x) { int y; if(x > 0) y = (int)(x + 0.5); //int will round down, so if the decimal of x is .5 or higher this will round up. else if(x < 0) y = (int)(x - 0.5); // the same but opposite return y; } #else byte size,s;//s=size*size #endif void cross(byte sy,byte sx,chtype start,chtype middle,chtype end){ //to simplify drawing tables. doesn't draw a cross (why did I choose that name?) mvaddch(sy,sx,start); byte f = 2*size; for(char n=1;ns) return 1; for(byte y=0;ys) board[y][x]=int2sgn(k=1); } ++k; if(k>s) k=1; } } for(byte n=0;n4) printw(" (some of these alphabet controls maybe overrided in certain sizes)"); mvprintw(10,0,"? : Hint (not like in other games)"); mvprintw(11,0,"F1 & F2: Help on controls & gameplay"); mvprintw(12,0,"PgDn,PgUp,<,> : Scroll"); mvprintw(15,0,"Press a key to continue"); refresh(); getch(); erase(); } void gameplay(void){ erase(); header(0,0); attron(A_BOLD); mvprintw(3,0," **** THE GAMEPLAY ****"); attroff(A_BOLD); move(4,0); printw("Fill the table with digits"); if(size>3) printw(" (and characters) \n"); else addch('\n'); printw("so that all the rows, columns and smaller subregions \n"); printw("contain all of the digits from 1 to "); if(size<=3){ addch(int2sgn(s)); addch('.'); } if(size>3){ addch('9'); printw(" and all\nthe alphabet letters from 'a' to '%c'.",int2sgn(s)); } printw("\n\nPress a key to continue."); refresh(); getch(); erase(); } int main(int argc,char** argv){ signal(SIGINT,sigint_handler); #ifndef Plan9 if(argc>4 || (argc==2 && !strcmp("help",argv[1])) ){ printf("Usage: %s [size [ difficulty]] \n",argv[0]); return EXIT_FAILURE; } if(argc>1 ){ if(strlen(argv[1])>1 || argv[1][0]-'0'>7 || argv[1][0]-'0'< 2){ printf("2 <= size <= 7\n"); return EXIT_FAILURE; } else size = *argv[1]-'0'; } else size=3; if(argc>2){ if (strlen(argv[2])>1 || argv[2][0]-'0'>4 || argv[2][0]-'0'<= 0 ){ printf("1 <= diff <=4\n"); return EXIT_FAILURE; } else diff = *argv[2]-'0'+1; } else diff=2; #else //Plan9 doesn't take size if(argc>2 || (argc==2 && !strcmp("help",argv[1])) ){ printf("Usage: %s [difficulty]\n",argv[0]); return EXIT_FAILURE; } if(argc>1){ if (strlen(argv[2])>1 || argv[2][0]-'0'>4 || argv[2][0]-'0'<= 0 ){ printf("1 <= diff <=4\n"); return EXIT_FAILURE; } else diff = *argv[2]-'0'+1; } else diff=2; #endif bool fastgen= !(!getenv("SUDOKU_FASTGEN")); initscr(); #ifndef NO_MOUSE mousemask(ALL_MOUSE_EVENTS,NULL); #endif //NO_MOUSE noecho(); cbreak(); keypad(stdscr,1); srand(time(NULL)%UINT_MAX); if( has_colors() ){ start_color(); use_default_colors(); init_pair(1,COLOR_YELLOW,-1); init_pair(2,COLOR_GREEN,-1); init_pair(3,COLOR_BLUE,-1); init_pair(4,COLOR_CYAN,-1); init_pair(5,COLOR_MAGENTA,-1); init_pair(6,COLOR_RED,-1); for(byte b=0;b<6;++b){ colors[b]=COLOR_PAIR(b+1); } } #ifndef Plan9 s= size*size; #endif char board[s][s]; char empty[s][s]; char game[s][s]; int input=0; int sy,sx; Start: sy=sx=0; erase(); curs_set(0); filled =0; memset(board,0,s*s); memset(empty,0,s*s); memset(game,0,s*s); if(fastgen) justfill(board); else fill(board); mkpuzzle(board,empty,game); py=px=0; while(1){ erase(); draw(sy+3,sx+0,empty,game); header(sy+0,sx+0); refresh(); if(filled == s*s) break; input = getch(); if( input==KEY_PPAGE && LINES< s+size+3){//the board starts in 3 sy+=10; if(sy>0) sy=0; } if( input==KEY_NPAGE && LINES< s+size+3){ sy-=10; if(sy< -(s+size+3) ) sy=-(s+size+3); } if( input=='<' && COLS< s*2){ sx+=10; if(sx>0) sx=0; } if( input=='>' && COLS< s*2){ sx-=10; if(sx< -(s*2)) sx=-(s*2); } if(input == KEY_F(1)) help(); if(input == KEY_F(2)) gameplay(); if(input == KEY_MOUSE) mouseinput(sy,sx); if(input == KEY_UP && py) --py; if(input == KEY_DOWN && py