pass.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. //
  2. // File: pass.c
  3. // pass.c plays the password guessing game
  4. // @author Josh Bicking <josh1147582>
  5. // // // // // // // // // // // // // // // // // // // // // // //
  6. #define _BSD_SOURCE // for unistd.h
  7. #ifdef _WIN32
  8. # include <Windows.h>
  9. # include <curses.h>
  10. # define SLEEP(delay) Sleep(delay/1000)
  11. #else
  12. # include <ncurses.h>
  13. # include <unistd.h>
  14. # define SLEEP(delay) usleep(delay)
  15. #endif
  16. #include <time.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include "pass.h"
  20. #include "print.h"
  21. #include "wordParse.h"
  22. #include "intro.h"
  23. #define OFFSET_LEFT 0
  24. #define OFFSET_RIGHT 20
  25. #define BIGSTRING_SIZE 408
  26. static int currentCharContains(char arr[],char c){
  27. int i;
  28. for(i=0; i<12; i++)
  29. if(arr[i]==c)
  30. return 1;
  31. return 0;
  32. }
  33. static int getCharLoc(int y, int x){
  34. // Left side
  35. if(x<19)
  36. return 12*(y-5)+(x-7);
  37. // Right side
  38. else
  39. return 12*(y-5)+(x-27+204);
  40. }
  41. void pass(){
  42. // Clear the screen
  43. erase();
  44. // Intro text
  45. passPrint("ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL",0);
  46. passPrint("ENTER PASSWORD NOW", 1);
  47. passPrint("4 ATTEMPT(S) LEFT: * * * *", 3);
  48. // Generate the hex values on the left sides
  49. int arbHex;
  50. arbHex = (rand() % 200) + 63744;
  51. // Generate the string to hold the bracket tricks and words
  52. char bigString [BIGSTRING_SIZE];
  53. char randValues[] = "!@#$%^*()_-=+\\|/[]{}?\"\':;,.<>";
  54. int i;
  55. for(i=0; i<BIGSTRING_SIZE; i++){
  56. // Fill bigString with random values
  57. bigString[i] = randValues[rand()%29];
  58. }
  59. char ** wordArr = getWordArr();
  60. int WORD_POOL_SIZE = getNumWords();
  61. int WORD_SIZE = getWordLength();
  62. int WORDS_CHOSEN = getWordsToChoose();
  63. // Place a word in the string total times, making sure it doesn
  64. // overwrite another word or get placed right next to it
  65. int place; // Current place for checking and word insertion
  66. int takenWords[WORDS_CHOSEN]; // Words already placed in bigString
  67. for(int i=0; i<WORDS_CHOSEN; i++)
  68. takenWords[i] = 0;
  69. int valid; // 1 if selected word is not already used a
  70. // does not conflict with other words, 0 otherwise */
  71. int pickedWord = 0; // Indicate whether or not we've chosen the correct word
  72. int left = WORDS_CHOSEN; // # of words that still need to be chosen
  73. char correctWord[WORD_SIZE]; // the correct word
  74. while(left>0){
  75. valid = 1;
  76. // Choose a random place in bigString
  77. place = rand()%(BIGSTRING_SIZE-WORD_SIZE);
  78. // Check of any characters there or around it are A-Z
  79. for(i=place-1; i<place+WORD_SIZE+1; i++){
  80. if(bigString[i] > 64 && bigString[i] < 91){
  81. valid = 0;
  82. break;
  83. }
  84. }
  85. if(valid){
  86. int wordLoc = rand()%WORD_POOL_SIZE;
  87. if(takenWords[wordLoc])
  88. valid=0;
  89. if(valid){
  90. takenWords[wordLoc] = 1;
  91. // Add the word to bigString
  92. for(i=place; i<place+WORD_SIZE; i++){
  93. bigString[i] = *(*(wordArr+wordLoc)+(i-place));
  94. // If this is the first word chosen, it is the correct word.
  95. if(!pickedWord)
  96. correctWord[i-place] = *(*(wordArr+wordLoc)+(i-place));
  97. }
  98. pickedWord = 1;
  99. left--;
  100. }
  101. }
  102. }
  103. // Create and fill an array to keep track of which brackets were used
  104. int usedBrackets[BIGSTRING_SIZE];
  105. for(i=0; i<BIGSTRING_SIZE; i++){
  106. usedBrackets[i] = 1;
  107. }
  108. // Print the hex and the filled bigString
  109. char temp[12];
  110. int current = 0;
  111. for(i=5; i<22; i++){
  112. // Print left side
  113. for(int j=0; j<12; j++){
  114. temp[j] = bigString[j+current];
  115. }
  116. printChoices(arbHex,temp,i, OFFSET_LEFT);
  117. current = current + 12;
  118. arbHex = arbHex + 12;
  119. }
  120. for(i=5; i<22; i++){
  121. // Print right side
  122. for(int j=0; j<12; j++){
  123. temp[j] = bigString[j+current];
  124. }
  125. printChoices(arbHex,temp,i, OFFSET_RIGHT);
  126. current = current + 12;
  127. arbHex = arbHex + 12;
  128. }
  129. mvprintw(21,40,"%c",'>');
  130. move(5,7);
  131. char currentChar[12]; // Max length currentChar could be (total possible length of a bracket trick)
  132. currentChar[0] = (char)mvinch(5,7);
  133. int y,x,origy,origx,starty,startx; // values that keep track of current yx locations, and original ones
  134. int wordLength; // How long a word is
  135. int charStart; // where character counting starts for brackets
  136. int keyPress; // key pressed by user
  137. int charCounter; // counts currentChar - used for incrementing currentChar to print or change it
  138. int bracketLength; // length of a bracket trick
  139. char endBracket; // the end bracket that corresponds to currentChar[0];
  140. int bracketTricks=0; // Total number of bracket tricks used
  141. int needsClearing = 0; // Whether or not highlights need to be pur
  142. int needsClearingMultiLine = 0; // Whether or not a multi line highlight needs to be purged
  143. char output[13]; // Used for side terminal output
  144. int allowances = 4;
  145. // Get the key config
  146. int GO_LEFT, GO_RIGHT, GO_DOWN, GO_UP;
  147. switch(getKeyConfig()){
  148. case ARROWS:
  149. GO_LEFT = KEY_LEFT;
  150. GO_RIGHT = KEY_RIGHT;
  151. GO_UP = KEY_UP;
  152. GO_DOWN = KEY_DOWN;
  153. break;
  154. case WASD:
  155. GO_LEFT = 'a';
  156. GO_RIGHT = 'd';
  157. GO_UP = 'w';
  158. GO_DOWN = 's';
  159. break;
  160. case HJKL:
  161. GO_LEFT = 'h';
  162. GO_RIGHT = 'l';
  163. GO_UP = 'k';
  164. GO_DOWN = 'j';
  165. break;
  166. }
  167. // Get rid of all typed characters
  168. int ch = getch();
  169. while(ch != ERR)
  170. ch = getch();
  171. // Finally, set nodelay to false so we can wait for input
  172. nodelay(stdscr, 0);
  173. while(1){
  174. getyx(stdscr,y,x);
  175. // Get allowances left
  176. mvprintw(1,0," ");
  177. mvprintw(3,0," ");
  178. switch(allowances){
  179. case 1: mvprintw(3,0,"1 ATTEMPT(S) LEFT: *");
  180. attron(A_BLINK);
  181. mvprintw(1,0,"!!! WARNING: LOCKOUT IMNINENT !!!");
  182. attroff(A_BLINK);
  183. attron(A_BOLD);
  184. break;
  185. case 2: mvprintw(3,0,"2 ATTEMPT(S) LEFT: * *");
  186. mvprintw(1,0,"ENTER PASSWORD NOW");
  187. break;
  188. case 3: mvprintw(3,0,"3 ATTEMPT(S) LEFT: * * *");
  189. mvprintw(1,0,"ENTER PASSWORD NOW");
  190. break;
  191. case 4: mvprintw(3,0,"4 ATTEMPT(S) LEFT: * * * *");
  192. mvprintw(1,0,"ENTER PASSWORD NOW");
  193. break;
  194. case 0: clear();
  195. mvprintw(10,20,"TERMINAL LOCKED");
  196. mvprintw(12,12,"PLEASE CONTACT AN ADMINISTRATOR");
  197. refresh();
  198. SLEEP(3000000);
  199. endwin();
  200. if(strlen(getCompleteProg())> 2)
  201. system(getCompleteProg());
  202. freeAll();
  203. exit(EXIT_FAILURE);
  204. }
  205. refresh();
  206. move(y,x);
  207. // Check if highlights need to be purged
  208. if(needsClearing){
  209. charCounter = 0;
  210. while(charCounter!=bracketLength+1){
  211. currentChar[charCounter] = (char)mvinch(origy,charStart+charCounter);
  212. mvprintw(origy,charStart+charCounter,"%c",(int)currentChar[charCounter]);
  213. charCounter++;
  214. }
  215. mvprintw(21,41," ",currentChar[0]);
  216. needsClearing = 0;
  217. move(y,origx);
  218. }
  219. if(needsClearingMultiLine){
  220. charCounter = 0;
  221. while(charCounter!=wordLength){
  222. currentChar[charCounter] = (char)mvinch(starty,startx);
  223. mvprintw(starty,startx,"%c",currentChar[charCounter]);
  224. charCounter++;
  225. startx++;
  226. if(startx==19 || startx==39){
  227. startx-=12;
  228. starty++;
  229. if(starty == 22) {
  230. starty = 5;
  231. startx+=20;
  232. }
  233. }
  234. }
  235. mvprintw(21,41," ",currentChar[0]);
  236. needsClearingMultiLine = 0;
  237. move(y,x);
  238. }
  239. // Clear the char array
  240. for(i=0;i<12;i++)
  241. currentChar[i]=' ';
  242. currentChar[0] = (char) (char)mvinch(y,x);
  243. // Set the new y and x to origy and origx
  244. origy = y;
  245. origx = x;
  246. // Check for bracket tricks
  247. if((currentChar[0]=='(' || currentChar[0]=='<' || currentChar[0]=='[' || currentChar[0]=='{') && usedBrackets[getCharLoc(y,x)] && bracketTricks<WORDS_CHOSEN){
  248. charStart = x;
  249. bracketLength=0;
  250. while(x!=18 && x!=38){
  251. x++;
  252. endBracket = (char)mvinch(y,x);
  253. bracketLength++;
  254. if((endBracket == ')' && currentChar[0]=='(') ||
  255. (endBracket == '>' && currentChar[0]=='<') ||
  256. (endBracket == ']' && currentChar[0]=='[') ||
  257. (endBracket == '}' && currentChar[0]=='{')){
  258. // Reprint the bracket trick with highlight
  259. attron(A_STANDOUT);
  260. charCounter = 0;
  261. while(1){
  262. currentChar[charCounter] = (char)mvinch(y,charStart+charCounter);
  263. mvprintw(y,charStart+charCounter,"%c",currentChar[charCounter]);
  264. if(currentChar[charCounter] == endBracket)
  265. break;
  266. charCounter++;
  267. }
  268. attroff(A_STANDOUT);
  269. // Print the bracket trick to output
  270. attron(A_BOLD);
  271. for(i=0;i<=charCounter;i++)
  272. mvprintw(21,41+i,"%c",(int)currentChar[i]);
  273. // Notify that highlighting will need to be cleared next move
  274. needsClearing = 1;
  275. }
  276. }
  277. if(!((endBracket == ')' && currentChar[0]=='(') ||
  278. (endBracket == '>' && currentChar[0]=='<') ||
  279. (endBracket == ']' && currentChar[0]=='[') ||
  280. (endBracket == '}' && currentChar[0]=='{'))){
  281. mvprintw(21,41,"%c",currentChar[0]);
  282. }
  283. }
  284. // Check for letters
  285. else if(currentChar[0]>64 && currentChar[0]<91){
  286. // Check for letter behind the current location
  287. int tempx = x;
  288. int tempy = y;
  289. while(bigString[getCharLoc(tempy,tempx)-1]>64 && bigString[getCharLoc(tempy,tempx)-1]<91){
  290. currentChar[0] = bigString[getCharLoc(tempy,tempx)];
  291. tempx--;
  292. if(tempx==6 || tempx==26){
  293. tempx+=12;
  294. tempy--;
  295. if(tempy == 4){
  296. tempy = 21;
  297. tempx-=20;
  298. }
  299. }
  300. }
  301. startx = tempx;
  302. starty = tempy; // We'll need the location of the first char for clean
  303. // And start there
  304. charCounter = 0;
  305. while(bigString[getCharLoc(tempy,tempx)+1]>64 && bigString[getCharLoc(tempy,tempx)+1]<91){
  306. currentChar[charCounter] = bigString[getCharLoc(tempy,tempx)];
  307. charCounter++;
  308. tempx++;
  309. if(tempx==19 || tempx==39){
  310. tempx-=12;
  311. tempy++;
  312. if(tempy == 22) {
  313. tempy = 5;
  314. tempx+=20;
  315. }
  316. }
  317. }
  318. // Now currentChar is the String, and charCounter+1 is the length
  319. wordLength = charCounter+1;
  320. // Reprint the word with highlight
  321. tempx = startx;
  322. tempy = starty;
  323. attron(A_STANDOUT);
  324. charCounter = 0;
  325. while(charCounter!=wordLength){
  326. currentChar[charCounter] = (char)mvinch(tempy,tempx);
  327. mvprintw(tempy,tempx,"%c",currentChar[charCounter]);
  328. charCounter++;
  329. tempx++;
  330. if(tempx==19 || tempx==39){
  331. tempx-=12;
  332. tempy++;
  333. if(tempy == 22) {
  334. tempy = 5;
  335. tempx+=20;
  336. }
  337. }
  338. }
  339. attroff(A_STANDOUT);
  340. // Print the word to output
  341. attron(A_BOLD);
  342. for(i=0;i<charCounter;i++)
  343. mvprintw(21,41+i,"%c",(int)currentChar[i]);
  344. // Notify that highlighting will need to be cleared next move
  345. needsClearingMultiLine = 1;
  346. }
  347. // Nothing was found, print current char
  348. else
  349. mvprintw(21,41,"%c",currentChar[0]);
  350. move(origy,origx);
  351. refresh();
  352. keyPress = getch();
  353. getyx(stdscr,y,x);
  354. if(keyPress==GO_UP){
  355. if(y>5)
  356. move(y-1,x);
  357. }
  358. if(keyPress==GO_DOWN){
  359. if(y<21)
  360. move(y+1,x);
  361. }
  362. if(keyPress==GO_LEFT){
  363. if(x>7){
  364. if(x==27)
  365. move(y,18);
  366. else
  367. move(y,x-1);
  368. }
  369. }
  370. if(keyPress==GO_RIGHT){
  371. if(x<38){
  372. if(x==18)
  373. move(y,27);
  374. else
  375. move(y,x+1);
  376. }
  377. }
  378. if(keyPress==3) // Ctrl-C
  379. exit(0);
  380. if(keyPress=='\n'){ // Enter
  381. // Get past answers and shift them up along the right.
  382. // This "log" handles 5 preivous commands.
  383. mvprintw(5,41," ");
  384. mvprintw(6,41," ");
  385. mvprintw(7,41," ");
  386. char buf[15];
  387. for(int i=8; i<19; i+=3) {
  388. for(int j=0; j< 3; j++){
  389. mvinnstr(i+j, 40, buf, 14);
  390. mvprintw(i+j,40," ");
  391. mvprintw(i+j-3, 40, "%s", buf);
  392. }
  393. }
  394. // If the char is a left bracket
  395. if(((currentChar[0]=='(') && currentCharContains(currentChar,')')) ||
  396. (currentChar[0]=='<' && currentCharContains(currentChar,'>')) ||
  397. (currentChar[0]=='[' && currentCharContains(currentChar,']')) ||
  398. (currentChar[0]=='{' && currentCharContains(currentChar,'}'))){
  399. // Set the selected bracket as used
  400. usedBrackets[getCharLoc(y,x)] = 0;
  401. // Increment total bracket tricks used
  402. bracketTricks++;
  403. if(rand()%5==0){
  404. // 20% chance of allowance replenish
  405. mvinnstr(21,40, buf, 14);
  406. mvprintw(17,40, "%s", buf);
  407. sprintf(output,"Allowance ");
  408. mvprintw(18,40,">");
  409. for(i=0;i<12;i++){
  410. mvprintw(18,41+i,"%c",output[i]);
  411. }
  412. sprintf(output,"replenished.");
  413. mvprintw(19,40,">");
  414. for(i=0;i<12;i++){
  415. mvprintw(19,41+i,"%c",output[i]);
  416. }
  417. allowances = 4;
  418. }
  419. else{
  420. // Remove a dud
  421. int tempx,tempy;
  422. pickagain:do{
  423. if(rand()%2==0)
  424. tempx = (rand()%12)+7;
  425. else
  426. tempx = (rand()%12)+27;
  427. tempy = (rand()%17)+5;
  428. } while(!(bigString[getCharLoc(tempy,tempx)]>64 && bigString[getCharLoc(tempy,tempx)]<91));
  429. while(bigString[getCharLoc(tempy,tempx)-1]>64 && bigString[getCharLoc(tempy,tempx)-1]<91){
  430. tempx--;
  431. if(tempx==6 || tempx==26){
  432. tempx+=12;
  433. tempy--;
  434. }
  435. }
  436. startx = tempx;
  437. starty = tempy;
  438. charCounter = 0;
  439. while(bigString[getCharLoc(tempy,tempx)+1]>64 && bigString[getCharLoc(tempy,tempx)+1]<91){
  440. currentChar[charCounter] = bigString[getCharLoc(tempy,tempx)];
  441. charCounter++;
  442. tempx++;
  443. if(tempx==19 || tempx==39){
  444. tempx-=12;
  445. tempy++;
  446. }
  447. }
  448. // Check if currentChar = correctWord
  449. int allCorrect=1;
  450. for(i=0;i<WORD_SIZE;i++){
  451. if(currentChar[i]!=correctWord[i])
  452. allCorrect = 0;
  453. }
  454. if(allCorrect)
  455. goto pickagain;
  456. tempx = startx;
  457. tempy = starty;
  458. while(bigString[getCharLoc(tempy,tempx)]>64 && bigString[getCharLoc(tempy,tempx)]<91){
  459. mvprintw(tempy,tempx,"%c",'.');
  460. bigString[getCharLoc(tempy,tempx)] = '.';
  461. tempx++;
  462. if(tempx==19 || tempx==39){
  463. tempx-=12;
  464. tempy++;
  465. }
  466. }
  467. mvinnstr(21,40, buf, 14);
  468. mvprintw(17,40, "%s", buf);
  469. mvprintw(18,40,">Dud");
  470. mvprintw(19,40,">removed.");
  471. }
  472. }
  473. // Else compare it to the correct word
  474. else{
  475. int rightLetters = WORD_SIZE;
  476. for(i=0;i<WORD_SIZE; i++){
  477. if(currentChar[i]!=correctWord[i])
  478. rightLetters--;
  479. }
  480. if(rightLetters==WORD_SIZE){
  481. mvprintw(15,40,">");
  482. for(i=0;i<12;i++){
  483. mvprintw(15,41+i,"%c",currentChar[i]);
  484. }
  485. sprintf(output,"Exact match!");
  486. mvprintw(16,40,">");
  487. for(i=0;i<12;i++){
  488. mvprintw(16,41+i,"%c",output[i]);
  489. }
  490. sprintf(output,"Please wait ");
  491. mvprintw(17,40,">");
  492. for(i=0;i<12;i++){
  493. mvprintw(17,41+i,"%c",output[i]);
  494. }
  495. sprintf(output,"while system");
  496. mvprintw(18,40,">");
  497. for(i=0;i<12;i++){
  498. mvprintw(18,41+i,"%c",output[i]);
  499. }
  500. sprintf(output,"is accessed.");
  501. mvprintw(19,40,">");
  502. for(i=0;i<12;i++){
  503. mvprintw(19,41+i,"%c",output[i]);
  504. }
  505. refresh();
  506. SLEEP(3000000);
  507. endwin();
  508. if(strlen(getVictoryProg()) > 2)
  509. system(getVictoryProg());
  510. else if(strlen(getCompleteProg())> 2)
  511. system(getCompleteProg());
  512. freeAll();
  513. exit(EXIT_SUCCESS);
  514. }
  515. else{
  516. mvprintw(17,40,">");
  517. for(i=0;i<12;i++){
  518. mvprintw(17,41+i,"%c",currentChar[i]);
  519. }
  520. sprintf(output,"Entry denied");
  521. mvprintw(18,40,">");
  522. for(i=0;i<12;i++){
  523. mvprintw(18,41+i,"%c",output[i]);
  524. }
  525. sprintf(output,"%d/%d correct.",rightLetters,WORD_SIZE);
  526. mvprintw(19,40,">");
  527. for(i=0;i<12;i++){
  528. mvprintw(19,41+i,"%c",output[i]);
  529. }
  530. allowances--;
  531. }
  532. }
  533. move(y,x);
  534. }
  535. refresh();
  536. }
  537. endwin();
  538. freeAll();
  539. exit(EXIT_SUCCESS);
  540. }