Advertisement
Guest User

PSET3 fifteen

a guest
Mar 16th, 2016
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.60 KB | None | 0 0
  1. /**
  2. * fifteen.c
  3. *
  4. * Computer Science 50
  5. * Problem Set 3
  6. *
  7. * Implements Game of Fifteen (generalized to d x d).
  8. *
  9. * Usage: fifteen d
  10. *
  11. * whereby the board's dimensions are to be d x d,
  12. * where d must be in [DIM_MIN,DIM_MAX]
  13. *
  14. * Note that usleep is obsolete, but it offers more granularity than
  15. * sleep and is simpler to use than nanosleep; `man usleep` for more.
  16. */
  17.  
  18. #define _XOPEN_SOURCE 500
  19.  
  20. #include <cs50.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <unistd.h>
  24.  
  25. // constants
  26. #define DIM_MIN 3
  27. #define DIM_MAX 9
  28.  
  29. // board
  30. int board[DIM_MAX][DIM_MAX];
  31.  
  32. // dimensions
  33. int d;
  34.  
  35. // prototypes
  36. void clear(void);
  37. void greet(void);
  38. void init(void);
  39. void draw(void);
  40. bool move(int tile);
  41. bool won(void);
  42.  
  43. int main(int argc, string argv[])
  44. {
  45. // ensure proper usage
  46. if (argc != 2)
  47. {
  48. printf("Usage: fifteen d\n");
  49. return 1;
  50. }
  51.  
  52. // ensure valid dimensions
  53. d = atoi(argv[1]);
  54. if (d < DIM_MIN || d > DIM_MAX)
  55. {
  56. printf("Board must be between %i x %i and %i x %i, inclusive.\n",
  57. DIM_MIN, DIM_MIN, DIM_MAX, DIM_MAX);
  58. return 2;
  59. }
  60.  
  61. // open log
  62. FILE* file = fopen("log.txt", "w");
  63. if (file == NULL)
  64. {
  65. return 3;
  66. }
  67.  
  68. // greet user with instructions
  69. greet();
  70.  
  71. // initialize the board
  72. init();
  73.  
  74. // accept moves until game is won
  75. while (true)
  76. {
  77. // clear the screen
  78. clear();
  79.  
  80. // draw the current state of the board
  81. draw();
  82.  
  83. // log the current state of the board (for testing)
  84. for (int i = 0; i < d; i++)
  85. {
  86. for (int j = 0; j < d; j++)
  87. {
  88. fprintf(file, "%i", board[i][j]);
  89. if (j < d - 1)
  90. {
  91. fprintf(file, "|");
  92. }
  93. }
  94. fprintf(file, "\n");
  95. }
  96. fflush(file);
  97.  
  98. // check for win
  99. if (won())
  100. {
  101. printf("ftw!\n");
  102. break;
  103. }
  104.  
  105. // prompt for move
  106. printf("Tile to move: ");
  107. int tile = GetInt();
  108.  
  109. // quit if user inputs 0 (for testing)
  110. if (tile == 0)
  111. {
  112. break;
  113. }
  114.  
  115. // log move (for testing)
  116. fprintf(file, "%i\n", tile);
  117. fflush(file);
  118.  
  119. // move if possible, else report illegality
  120. if (!move(tile))
  121. {
  122. printf("\nIllegal move.\n");
  123. usleep(500000);
  124. }
  125.  
  126. // sleep thread for animation's sake
  127. usleep(500000);
  128. }
  129.  
  130. // close log
  131. fclose(file);
  132.  
  133. // success
  134. return 0;
  135. }
  136.  
  137. /**
  138. * Clears screen using ANSI escape sequences.
  139. */
  140. void clear(void)
  141. {
  142. printf("\033[2J");
  143. printf("\033[%d;%dH", 0, 0);
  144. }
  145.  
  146. /**
  147. * Greets player.
  148. */
  149. void greet(void)
  150. {
  151. clear();
  152. printf("WELCOME TO GAME OF FIFTEEN\n");
  153. usleep(2000000);
  154. }
  155.  
  156. /**
  157. * Initializes the game's board with tiles numbered 1 through d*d - 1
  158. * (i.e., fills 2D array with values but does not actually print them).
  159. */
  160. void init(void)
  161. {
  162. // largest number in gameboard
  163. int currentNum = (d * d) - 1;
  164.  
  165. // loop for rows
  166. for (int j = 0; j < d; j++)
  167. {
  168. // loop for a single row
  169. for (int i = 0; i < d; i++)
  170. {
  171. // number decreases by 1 every time
  172. board[j][i] = currentNum - i;
  173.  
  174. // if d is odd, and the loop is at its final iteration
  175. if (((d % 2) == 1) && (j == d - 1) && (i == d - 1))
  176. {
  177. // switch numbers 2 and 1
  178. board[j][i--] = 2;
  179. board[j--][i - 2] = 1;
  180. }
  181. // if board is at final iteration
  182. if (((j == d - 1) && (i == d - 1)))
  183. {
  184. // set the last number of the board to 0
  185. board[j][i] = 0;
  186. }
  187. }
  188. }
  189. }
  190.  
  191. /**
  192. * Prints the board in its current state.
  193. */
  194. void draw(void)
  195. {
  196. // loop for rows
  197. for (int j = 0; j < d; j++)
  198. {
  199. // loop for a single row
  200. for (int i = 0; i < d; i++)
  201. {
  202. // if the board loop is not at 0
  203. if (board[j][i] != 0)
  204. {
  205. // print the corresponding number
  206. printf("%i", board[j][i]);
  207. printf(" ");
  208. }
  209. // if board loop is at 0
  210. else
  211. {
  212. // print _
  213. printf("_");
  214. }
  215. }
  216. // new line after every individual row loop
  217. printf("\n");
  218. }
  219. }
  220.  
  221. /**
  222. * If tile borders empty space, moves tile and returns true, else
  223. * returns false.
  224. */
  225. bool move(int tile)
  226. {
  227. // cycle through board, find location of tile
  228. for (int j = 0; j < d; j++)
  229. {
  230. for (int i = 0; i < d; i++)
  231. {
  232. // check possible adjacent locations of the empty space
  233. if (board[j][i] == tile)
  234. {
  235. if (board[j - 1][i] == 0)
  236. {
  237. board[j - 1][i] = board[j][i];
  238. board[j][i] = 0;
  239. return true;
  240. }
  241. else if (board[j + 1][i] == 0)
  242. {
  243. board[j + 1][i] = board[j][i];
  244. board[j][i] = 0;
  245. return true;
  246. }
  247. else if (board[j][i - 1] == 0)
  248. {
  249. board[j][i - 1] = board[j][i];
  250. board[j][i] = 0;
  251. return true;
  252. }
  253. else if (board[j][i + 1] == 0)
  254. {
  255. board[j][i + 1] = board[j][i];
  256. board[j][i] = 0;
  257. return true;
  258. }
  259. }
  260. }
  261. }
  262. return false;
  263. }
  264.  
  265. /**
  266. * Returns true if game is won (i.e., board is in winning configuration),
  267. * else false.
  268. */
  269. bool won(void)
  270. {
  271. // convert the 2-dimensional array of the board to a single dimension array
  272. int boardVals[d * d];
  273.  
  274. for (int j = 0; j < d; j++)
  275. {
  276. for (int i = 0; i < d; i++)
  277. {
  278. for (int k = 0; k < (d * d); k++)
  279. {
  280. boardVals[k] = board[j][i];
  281. }
  282. }
  283. }
  284.  
  285. // if board is in order
  286. for (int l = 0; l < ((d * d) - 1); l++)
  287. {
  288. if (l != 0)
  289. {
  290. if (boardVals[l] < boardVals[l - 1])
  291. {
  292. return false;
  293. }
  294. }
  295. }
  296. return true;
  297. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement