#include #include #include #include //to seed random #include #include #include /* _ (_ _)UDOKU Authored by Hossein Bakhtiarifar No rights are reserved and this software comes with no warranties of any kind to the extent permitted by law. compile with -lncurses 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. */ typedef signed char byte; byte _wait=0, waitcycles=0;//apparently 'wait' conflicts with a variable in a library macOS includes by default byte size,s;//s=size*size byte py,px; byte diff; unsigned int filled; chtype colors[6]={0}; 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); 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; bool fastgen= !(!getenv("SUDOKU_FASTGEN")); initscr(); mousemask(ALL_MOUSE_EVENTS,NULL); noecho(); cbreak(); keypad(stdscr,1); srandom(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); } } s= size*size; 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