PageRenderTime 66ms CodeModel.GetById 41ms RepoModel.GetById 0ms app.codeStats 1ms

/Game.c

https://bitbucket.org/ashaw/cs1917-project-mon09spoons1
C | 1297 lines | 1140 code | 42 blank | 115 comment | 285 complexity | 5d0426bb8f134087804c216ecc28386a MD5 | raw file
  1. /*
  2. * Game.c
  3. * 1917 v2.0
  4. * Add to and change this file as you wish to implement the
  5. * interface functions in Game.h
  6. *
  7. * Created by Richard Buckland on 20/04/11.
  8. * Copyright 2011 Licensed under Creative Commons SA-BY-NC 3.0.
  9. * Copyright 2011 Licensed under Creative Commons SA-BY-NC 3.0.
  10. *
  11. */
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <assert.h>
  15. #include <string.h>
  16. #include <limits.h>
  17. #include "Game.h"
  18. #define NUM_DISCIPLINES 6
  19. #define NUM_VERTECIES 54
  20. #define NUM_EDGES 72
  21. //defines for rollDice
  22. #define NUM_VERTECIES_ARROUND_REGION 6
  23. #define CAMPUS 1
  24. #define GO8_CAMPUS 2
  25. #define GENERAL_RC 0
  26. // store in this struct all the things you might want to know about
  27. // the game so we can write the interface functions in the header.
  28. typedef int vertex;
  29. typedef int edge;
  30. typedef struct _region{
  31. int diceScore;
  32. int discipline;
  33. } region;
  34. typedef struct _board {
  35. vertex vertexes[11][11];
  36. edge edges[22][22];
  37. region regions[11][11];
  38. } board;
  39. typedef struct _board *Board;
  40. typedef struct _player {
  41. int students[NUM_DISCIPLINES];
  42. int IPs;
  43. int publications;
  44. int exchangeRate[NUM_DISCIPLINES][NUM_DISCIPLINES];
  45. int ARCs;
  46. int campuses;
  47. int GO8s;
  48. } player;
  49. typedef struct _game {
  50. Board gameBoard;
  51. player players[NUM_UNIS+1];
  52. int currentTurn;
  53. int mostARCs;
  54. int mostPublications;
  55. } game;
  56. typedef struct _edgeSpecifier{
  57. int x;
  58. int y;
  59. } edgeSpecifier;
  60. typedef struct _vertexSpecifier{
  61. int x;
  62. int y;
  63. } vertexSpecifier;
  64. typedef struct _regionSpecifier{
  65. int x;
  66. int y;
  67. } regionSpecifier;
  68. //static functions for initialisation
  69. static void initialisePlayer(Game g, int uni);
  70. static void initialiseBoard(Game g, int discipline[], int dice[]);
  71. //static functions for rollDice()
  72. static void convertMMoneyStudentsToTHD(Game g);
  73. static void convertMTVStudentsToTHD(Game g);
  74. static void distributeStudents (Game g, int diceScore);
  75. static int getTypeOfVertex(vertex input);
  76. static int getOwnerOfVertex(vertex input);
  77. //static functions for implementing the Board ADT;
  78. static Board createBoard(void);
  79. static void disposeBoard(Board gameBoard);
  80. static int isOnBoard(path pathToCheck);
  81. static void setVertex (Board b, vertexSpecifier vertexLocation,
  82. vertex vertexContents);
  83. static void setEdge (Board b, edgeSpecifier edgeLocation,
  84. edge edgeContents);
  85. static void setRegion (Board b, regionSpecifier regionSpecifier,
  86. region regionContents);
  87. static vertex getVertex (Board b, vertexSpecifier vertexLocation);
  88. static edge getEdge (Board b, edgeSpecifier edgeLocation);
  89. static region getRegion (Board b, regionSpecifier regionLocation);
  90. static edgeSpecifier getEdgeSpecifierFromPath (path edge);
  91. static vertexSpecifier getVertexSpecifierFromPath (path vertex);
  92. static edgeSpecifier getEdgeSpecifierFromIndex (int edgeIndex);
  93. static vertexSpecifier getVertexSpecifierFromIndex (int vertexIndex);
  94. static regionSpecifier getRegionSpecifierFromIndex (int regionIndex);
  95. static int isNextToRetrainingCenter(Board g,
  96. vertexSpecifier vertexLocation);
  97. static int getRetrainingCenterType (Board g,
  98. vertexSpecifier vertexLocation);
  99. static vertexSpecifier getSpecifierOfSpecialVertex(int specialLocation);
  100. static edgeSpecifier getSpecifierOfSpecialEdge(int SpecialLocation);
  101. static vertexSpecifier getVertexAdjacentToRegion (regionSpecifier input,
  102. int index);
  103. static vertexSpecifier getRightVertex(vertexSpecifier current,
  104. vertexSpecifier back);
  105. static vertexSpecifier getLeftVertex(vertexSpecifier current,
  106. vertexSpecifier back);
  107. static void getSurroundingVertecies(vertexSpecifier location,
  108. /*@out@*/vertexSpecifier output[3]);
  109. static void tracePath(vertexSpecifier current, vertexSpecifier back,
  110. path input, /*@null@*//*@out@*/ vertexSpecifier* p1,
  111. /*@null@*//*@out@*/ vertexSpecifier* p2);
  112. static int isVertex(int x, int y);
  113. static int isPointOnBoard(int row,int col);
  114. static int getArrayOfVertecies(/*@out@*/vertexSpecifier points[]);
  115. static int getArrayOfEdges(/*@out@*/ edgeSpecifier edges[]);
  116. //static Functions for isLegalAction
  117. static int isLegalToBuildCampus(Game g, path destination);
  118. static int isLegalToBuildGO8(Game g, path destination);
  119. static int isLegalToObtainArc(Game g, path destination);
  120. static int isLegalToStartSpinoff(Game g);
  121. static int isLegalToRetrainStudents(Game g, int disciplineFrom,
  122. int disciplineTo);
  123. static int isValidArcLocationForPlayer(Game g, path destination);
  124. static int isEdgeAdjacentToMyCampus(Game g, path destination);
  125. static int isEdgeAdjacentToMyEdge(Game g, path destination);
  126. static int isVertexAdjacentToCampus(Game g, path destination);
  127. static int isVertexAdjacentToMyArc(Game g, path destination);
  128. static int uniForCurrentPlayer(Game g);
  129. static int numGO8s(Game g);
  130. static int playerHasResources(Game g, int studentsNeeded[]);
  131. static int isLegalPath(path pathToCheck);
  132. /* **** Functions which change the game aka SETTERS **** */
  133. // make a new game, given the disciplines produced by each
  134. // region, and the value on the dice discs in each region.
  135. // note: each array must be NUM_REGIONS long
  136. // eg if you are using my sample game struct above this function
  137. // would need to set the field currentTurn to 0. (because the turn
  138. // number is 0 at the start of the game)
  139. Game newGame (int discipline[], int dice[]) {
  140. Game newGame;
  141. newGame = calloc(1, sizeof(*newGame));
  142. assert (newGame != NULL);
  143. //initialise the Game here
  144. initialisePlayer(newGame, UNI_A);
  145. initialisePlayer(newGame, UNI_B);
  146. initialisePlayer(newGame, UNI_C);
  147. //create a new Board
  148. newGame->gameBoard = createBoard();
  149. assert (newGame->gameBoard != NULL);
  150. initialiseBoard(newGame, discipline, dice);
  151. newGame->mostARCs = NO_ONE;
  152. newGame->mostPublications = NO_ONE;
  153. newGame->currentTurn = -1;
  154. return newGame;
  155. }
  156. static void initialisePlayer(Game g, int uni){
  157. int i, j; //annonymous loop counters;
  158. assert (g != NULL);
  159. g->players[uni].IPs = 0;
  160. g->players[uni].publications = 0;
  161. g->players[uni].ARCs = 2;
  162. g->players[uni].campuses = 2;
  163. g->players[uni].GO8s = 0;
  164. i=0;
  165. while (i<NUM_DISCIPLINES){
  166. g->players[uni].students [i]=0;
  167. i++;
  168. }
  169. //Set the default exchange rate. 3 becasue everyone starts on a
  170. //retraining center
  171. i=0;
  172. while (i<NUM_DISCIPLINES) {
  173. j=0;
  174. while (j<NUM_DISCIPLINES) {
  175. g->players[uni].exchangeRate[i][j] = 3;
  176. j++;
  177. }
  178. i++;
  179. }
  180. //set the exchange rate for STUDENT_THD to INT_MIN as the only sane
  181. //value
  182. i = 0;
  183. while (i< NUM_DISCIPLINES){
  184. g->players[uni].exchangeRate[0][STUDENT_THD] = INT_MAX;
  185. i++;
  186. }
  187. i = 0;
  188. while (i< NUM_DISCIPLINES){
  189. g->players[uni].exchangeRate[i][i] = 1;
  190. i++;
  191. }
  192. }
  193. static void initialiseBoard(Game g, int discipline[], int dice[]){
  194. edgeSpecifier edgeLocation;
  195. vertexSpecifier vertexLocation;
  196. regionSpecifier regionLocation;
  197. region regionContents;
  198. int i;
  199. assert (g != NULL);
  200. assert (g->gameBoard != NULL);
  201. i = 0;
  202. //initialise the board to blank
  203. while (i < NUM_VERTECIES){
  204. vertexLocation = getVertexSpecifierFromIndex (i);
  205. setVertex (g->gameBoard, vertexLocation, VACANT_VERTEX);
  206. i++;
  207. }
  208. i=0;
  209. while (i < NUM_EDGES){
  210. edgeLocation = getEdgeSpecifierFromIndex (i);
  211. setEdge (g->gameBoard, edgeLocation, VACANT_ARC);
  212. i++;
  213. };
  214. i=0;
  215. while (i < NUM_REGIONS){
  216. regionContents.diceScore = dice[i];
  217. regionContents.discipline = discipline[i];
  218. regionLocation = getRegionSpecifierFromIndex (i);
  219. setRegion (g->gameBoard, regionLocation, regionContents);
  220. i++;
  221. }
  222. /*----- Setup Default Campuses -----*/
  223. vertexLocation = getSpecifierOfSpecialVertex(0);
  224. setVertex (g->gameBoard, vertexLocation, CAMPUS_A);
  225. vertexLocation = getSpecifierOfSpecialVertex(3);
  226. setVertex (g->gameBoard, vertexLocation, CAMPUS_A);
  227. vertexLocation = getSpecifierOfSpecialVertex(1);
  228. setVertex (g->gameBoard, vertexLocation, CAMPUS_B);
  229. vertexLocation = getSpecifierOfSpecialVertex(4);
  230. setVertex (g->gameBoard, vertexLocation, CAMPUS_B);
  231. vertexLocation = getSpecifierOfSpecialVertex(2);
  232. setVertex (g->gameBoard, vertexLocation, CAMPUS_C);
  233. vertexLocation = getSpecifierOfSpecialVertex(5);
  234. setVertex (g->gameBoard, vertexLocation, CAMPUS_C);
  235. /*----- Setup Default ARCs -----*/
  236. edgeLocation = getSpecifierOfSpecialEdge(0);
  237. setEdge (g->gameBoard, edgeLocation, ARC_A);
  238. edgeLocation = getSpecifierOfSpecialEdge(3);
  239. setEdge (g->gameBoard, edgeLocation, ARC_A);
  240. edgeLocation = getSpecifierOfSpecialEdge(1);
  241. setEdge (g->gameBoard, edgeLocation, ARC_B);
  242. edgeLocation = getSpecifierOfSpecialEdge(4);
  243. setEdge (g->gameBoard, edgeLocation, ARC_B);
  244. edgeLocation = getSpecifierOfSpecialEdge(2);
  245. setEdge (g->gameBoard, edgeLocation, ARC_C);
  246. edgeLocation = getSpecifierOfSpecialEdge(5);
  247. setEdge (g->gameBoard, edgeLocation, ARC_C);
  248. }
  249. // after the break we will talk about implementing this. for now
  250. // you can have it doing nothing
  251. void disposeGame (Game g) {
  252. assert (g != NULL);
  253. assert (g->gameBoard != NULL);
  254. disposeBoard(g->gameBoard);
  255. free (g);
  256. }
  257. // make the specified action for the current player and update the
  258. // game state accordingly.
  259. // The function may assume that the action requested is legal.
  260. void makeAction (Game g, action a){
  261. int currentPlayer;
  262. edgeSpecifier edgeLocation;
  263. vertexSpecifier vertexLocation;
  264. int retrainingCenterType;
  265. int i, j;
  266. assert (g != NULL);
  267. currentPlayer = getWhoseTurn(g);
  268. //executes action PASS
  269. if(a.actionCode == PASS) {
  270. //do nothing
  271. } else if(a.actionCode == BUILD_CAMPUS) {
  272. //modifies the contents of the vertex
  273. vertexLocation = getVertexSpecifierFromPath (a.destination);
  274. setVertex (g->gameBoard, vertexLocation, (vertex)currentPlayer);
  275. //gives the current player a campus
  276. g->players[currentPlayer].campuses++;
  277. //taking away the student costs for building a campus
  278. g->players[currentPlayer].students[STUDENT_BPS]--;
  279. g->players[currentPlayer].students[STUDENT_BQN]--;
  280. g->players[currentPlayer].students[STUDENT_MJ]--;
  281. g->players[currentPlayer].students[STUDENT_MTV]--;
  282. //Checks if the vertex is Adjacent a retraining Centre and if so
  283. //Changes the exchange rate appropriately
  284. if (isNextToRetrainingCenter(g->gameBoard, vertexLocation)){
  285. retrainingCenterType = getRetrainingCenterType (g->gameBoard, vertexLocation);
  286. if(retrainingCenterType == GENERAL_RC){
  287. i=1; //do not change the exchange rate for STUDENT_THD
  288. while(i<NUM_DISCIPLINES){
  289. j = 0;
  290. while(j<NUM_DISCIPLINES){
  291. if(g->players[currentPlayer].exchangeRate[i][j] > 3){
  292. g->players[currentPlayer].exchangeRate[i][j] = 3;
  293. }
  294. if(g->players[currentPlayer].exchangeRate[i][i] > 3){
  295. g->players[currentPlayer].exchangeRate[j][i] = 3;
  296. }
  297. if(g->players[currentPlayer].exchangeRate[i][i] > 3){
  298. g->players[currentPlayer].exchangeRate[i][j] = 3;
  299. }
  300. if(g->players[currentPlayer].exchangeRate[i][j] > 3){
  301. g->players[currentPlayer].exchangeRate[i][j] = 3;
  302. }
  303. if(g->players[currentPlayer].exchangeRate[i][j] > 3){
  304. g->players[currentPlayer].exchangeRate[i][j] = 3;
  305. }
  306. if(g->players[currentPlayer].exchangeRate[i][j] > 3){
  307. g->players[currentPlayer].exchangeRate[i][j] = 3;
  308. }
  309. j++;
  310. }
  311. i++;
  312. }
  313. } else {
  314. i=0;
  315. while(i<NUM_DISCIPLINES){
  316. g->players[currentPlayer].exchangeRate[retrainingCenterType][i] = 2;
  317. i ++;
  318. }
  319. }
  320. }
  321. } else if(a.actionCode == BUILD_GO8) {
  322. //updates the contents of the vertex (the player number and codes for GO8s are off by 3)
  323. vertexLocation = getVertexSpecifierFromPath (a.destination);
  324. setVertex (g->gameBoard, vertexLocation, (vertex)(currentPlayer+3));
  325. //gives the current player a GO8
  326. g->players[currentPlayer].GO8s++;
  327. g->players[currentPlayer].campuses--;
  328. //taking away the student costs for building a GO8
  329. g->players[currentPlayer].students[STUDENT_MJ] -= 2;
  330. g->players[currentPlayer].students[STUDENT_MMONEY] -= 3;
  331. } else if(a.actionCode == OBTAIN_ARC) {
  332. //modifies the contents of the edge
  333. edgeLocation = getEdgeSpecifierFromPath (a.destination);
  334. setEdge (g->gameBoard, edgeLocation, (edge)currentPlayer);
  335. //gives the current player an ARC
  336. g->players[currentPlayer].ARCs++;
  337. //taking away the student costs for building an ARC
  338. g->players[currentPlayer].students[STUDENT_BPS]--;
  339. g->players[currentPlayer].students[STUDENT_BQN]--;
  340. //checks if the current player has the most ARCs
  341. if (g->players[getMostARCs(g)].ARCs < g->players[currentPlayer].ARCs) {
  342. //if so then modifies the game struct to signify
  343. g->mostARCs = currentPlayer;
  344. }
  345. } else if(a.actionCode == OBTAIN_PUBLICATION) {
  346. //give the current player a publication
  347. g->players[currentPlayer].publications++;
  348. //takes away the student costs for a spinoff
  349. g->players[currentPlayer].students[STUDENT_MJ]--;
  350. g->players[currentPlayer].students[STUDENT_MTV]--;
  351. g->players[currentPlayer].students[STUDENT_MMONEY]--;
  352. //checks if the current player has the most publications
  353. if (g->players[getMostPublications(g)].publications < g->players[currentPlayer].publications){
  354. //if so then modifies the game struct to signify
  355. g->mostPublications = currentPlayer;
  356. }
  357. } else if(a.actionCode == OBTAIN_IP_PATENT) {
  358. //gives the current player a patent
  359. g->players[currentPlayer].IPs++;
  360. //takes away the student costs for a spinoff
  361. g->players[currentPlayer].students[STUDENT_MJ]--;
  362. g->players[currentPlayer].students[STUDENT_MTV]--;
  363. g->players[currentPlayer].students[STUDENT_MMONEY]--;
  364. } else if(a.actionCode == RETRAIN_STUDENTS) {
  365. //adds one student of the discipline that the player wanted
  366. g->players[currentPlayer].students[a.disciplineTo]++;
  367. //takes away a certain amount of students according to the player's exchange rate for that discipline
  368. g->players[currentPlayer].students[a.disciplineFrom] -= getExchangeRate (g, currentPlayer, a.disciplineFrom, a.disciplineTo);
  369. } else {
  370. assert(FALSE);
  371. }
  372. }
  373. // advance the game to the next turn,
  374. // assuming that the dice has just been rolled and produced diceScore
  375. // the game starts in turn -1 (we call this state "Terra Nullis") and
  376. // moves to turn 0 as soon as the first dice is thrown.
  377. void throwDice (Game g, int diceScore){
  378. assert (g != NULL);
  379. if (diceScore == 7){
  380. convertMMoneyStudentsToTHD(g);
  381. convertMTVStudentsToTHD(g);
  382. }
  383. distributeStudents(g, diceScore);
  384. g->currentTurn ++;
  385. }
  386. static void distributeStudents (Game g, int diceScore){
  387. vertexSpecifier locationOfVertexOfInterest;
  388. regionSpecifier locationOfRegionOfInterest;
  389. region regionOfInterest;
  390. vertex vertexOfInterest;
  391. int typeOfVertex;
  392. int studentType;
  393. int university;
  394. int i, j;
  395. assert (g != NULL);
  396. assert (g->gameBoard != NULL);
  397. i = 0;
  398. while (i < NUM_REGIONS){
  399. locationOfRegionOfInterest = getRegionSpecifierFromIndex (i);
  400. regionOfInterest = getRegion (g->gameBoard, locationOfRegionOfInterest);
  401. if(regionOfInterest.diceScore == diceScore){
  402. j = 0;
  403. while (j < NUM_VERTECIES_ARROUND_REGION){
  404. studentType = regionOfInterest.discipline;
  405. locationOfVertexOfInterest = getVertexAdjacentToRegion (locationOfRegionOfInterest, j);
  406. vertexOfInterest = getVertex (g->gameBoard, locationOfVertexOfInterest);
  407. typeOfVertex = getTypeOfVertex(vertexOfInterest);
  408. university = getOwnerOfVertex(vertexOfInterest);
  409. if (typeOfVertex == VACANT_VERTEX){
  410. //do nothing
  411. } else if (typeOfVertex == CAMPUS){
  412. g->players[university].students[studentType] += 1;
  413. } else if (typeOfVertex == GO8_CAMPUS){
  414. g->players[university].students[studentType] += 2;
  415. } else {
  416. assert(FALSE);
  417. }
  418. j++;
  419. }
  420. }
  421. i++;
  422. }
  423. }
  424. static int getTypeOfVertex(vertex input){
  425. int returnValue;
  426. if ((input == CAMPUS_A)||(input == CAMPUS_B)||(input == CAMPUS_C)){
  427. returnValue = CAMPUS;
  428. } else if ((input == GO8_A)||(input == GO8_B)||(input == GO8_C)){
  429. returnValue = GO8_CAMPUS;
  430. } else {
  431. returnValue = VACANT_VERTEX;
  432. }
  433. return returnValue;
  434. }
  435. static int getOwnerOfVertex(vertex input){
  436. int returnValue;
  437. if((input == CAMPUS_A)||(input == GO8_A)){
  438. returnValue = UNI_A;
  439. } else if((input == CAMPUS_B)||(input == GO8_B)){
  440. returnValue = UNI_B;
  441. } else if((input == CAMPUS_C)||(input == GO8_C)){
  442. returnValue = UNI_C;
  443. } else {
  444. returnValue = NO_ONE;
  445. }
  446. return returnValue;
  447. }
  448. static void convertMTVStudentsToTHD(Game g){
  449. int numOfMTVStudents;
  450. int university = UNI_A;
  451. assert (g != NULL);
  452. while (university < (UNI_A + NUM_UNIS)){
  453. numOfMTVStudents = g->players[university].students[STUDENT_MTV];
  454. g->players[university].students[STUDENT_THD] += numOfMTVStudents;
  455. g->players[university].students[STUDENT_MTV] = 0;
  456. university++;
  457. }
  458. }
  459. static void convertMMoneyStudentsToTHD(Game g){
  460. int numOfMMoneyStudents;
  461. int university = UNI_A;
  462. assert (g != NULL);
  463. while (university < UNI_A + NUM_UNIS){
  464. numOfMMoneyStudents = g->players[university].students[STUDENT_MMONEY];
  465. g->players[university].students[STUDENT_THD] += numOfMMoneyStudents;
  466. g->players[university].students[STUDENT_MMONEY] = 0;
  467. university++;
  468. }
  469. }
  470. /* **** Functions which GET data about the game aka GETTERS **** */
  471. // what type of students are produced by the specified region?
  472. // see discipline codes above
  473. int getDiscipline (Game g, int regionID){
  474. regionSpecifier regionLocation;
  475. region regionValue;
  476. assert (g != NULL);
  477. assert (g->gameBoard != NULL);
  478. regionLocation = getRegionSpecifierFromIndex(regionID);
  479. regionValue = getRegion (g->gameBoard, regionLocation);
  480. return regionValue.discipline;
  481. }
  482. // what dice value produces students in the specified region?
  483. // 2..12
  484. int getDiceValue (Game g, int regionID){
  485. regionSpecifier regionLocation;
  486. region regionValue;
  487. assert (g != NULL);
  488. assert (g->gameBoard != NULL);
  489. regionLocation = getRegionSpecifierFromIndex(regionID);
  490. regionValue = getRegion (g->gameBoard, regionLocation);
  491. return regionValue.diceScore;
  492. }
  493. // which university currently has the prestige award for the most ARCs?
  494. // this is NO_ONE until the first arc is purchased after the game
  495. // has started.
  496. int getMostARCs (Game g){
  497. assert(g != NULL);
  498. return g->mostARCs;
  499. }
  500. // which university currently has the prestige award for the most IP?
  501. // this is NO_ONE until the first IP is patented after the game
  502. // has started.
  503. int getMostPublications (Game g){
  504. assert (g != NULL);
  505. return g->mostPublications;
  506. }
  507. // return the current turn number of the game -1,0,1, ..
  508. int getTurnNumber (Game g) {
  509. assert (g != NULL);
  510. return g->currentTurn;
  511. }
  512. // return the id of the player whose turn it is 0,1 ..NUM_UNIS
  513. // the result of this function is undefined during Terra Nullis
  514. // don't call it until the game has started.
  515. int getWhoseTurn (Game g){
  516. int whoseTurn;
  517. assert(g != NULL);
  518. if (g->currentTurn < 0){
  519. whoseTurn = NO_ONE;
  520. } else {
  521. whoseTurn = (g->currentTurn % NUM_UNIS) + UNI_A;
  522. }
  523. return whoseTurn;
  524. }
  525. // return the contents of the given vertex (ie campus code or
  526. // VACENT_VERTEX)
  527. int getCampus(Game g, path pathToVertex){
  528. vertexSpecifier vertexLocation;
  529. vertex vertexContents;
  530. assert (g != NULL);
  531. assert (g->gameBoard != NULL);
  532. if (isOnBoard(pathToVertex)){
  533. vertexLocation = getVertexSpecifierFromPath (pathToVertex);
  534. vertexContents = getVertex (g->gameBoard, vertexLocation);
  535. } else {
  536. vertexContents = VACANT_VERTEX;
  537. }
  538. return (int) vertexContents;
  539. }
  540. // the contents of the given edge (ie ARC code or vacent ARC)
  541. int getARC(Game g, path pathToEdge){
  542. edgeSpecifier edgeLocation;
  543. edge edgeContents;
  544. assert (g != NULL);
  545. assert (g->gameBoard != NULL);
  546. if(isOnBoard(pathToEdge)){
  547. edgeLocation = getEdgeSpecifierFromPath (pathToEdge);
  548. edgeContents = getEdge (g->gameBoard, edgeLocation);
  549. } else {
  550. edgeContents = VACANT_ARC;
  551. }
  552. return (int) edgeContents;
  553. }
  554. // returns TRUE if it is legal for the current
  555. // player to make the specified move, FALSE otherwise.
  556. // legal means everything is legal eg when placing a campus consider
  557. // such things as:
  558. // * is the specified path a valid path?
  559. // * does it lead to a vacent vertex?
  560. // * under the rules of the game are they allowed to place a
  561. // campus at that vertex? (eg is it adjacent to one of their ARCs?)
  562. // * does the player have the 4 specific students required to pay for
  563. // that campus?
  564. // It is not legal to make any action during Terra Nullis ie
  565. // before the game has started.
  566. // It is not legal for a player to make the moves OBTAIN_PUBLICATION
  567. // or OBTAIN_IP_PATENT (they can make the move START_SPINOFF)
  568. int isLegalAction (Game g, action a){
  569. int returnValue;
  570. if (a.actionCode == PASS){
  571. returnValue = TRUE;
  572. } else if (a.actionCode == BUILD_CAMPUS){
  573. returnValue = isLegalToBuildCampus(g, a.destination);
  574. } else if (a.actionCode == BUILD_GO8){
  575. returnValue = isLegalToBuildGO8(g, a.destination);
  576. } else if (a.actionCode == OBTAIN_ARC){
  577. returnValue = isLegalToObtainArc(g, a.destination);
  578. } else if (a.actionCode == START_SPINOFF){
  579. returnValue = isLegalToStartSpinoff(g);
  580. } else if (a.actionCode == OBTAIN_PUBLICATION){
  581. returnValue = FALSE;
  582. } else if (a.actionCode == OBTAIN_IP_PATENT){
  583. returnValue = FALSE;
  584. } else if (a.actionCode == RETRAIN_STUDENTS){
  585. returnValue = isLegalToRetrainStudents(g, a.disciplineFrom,
  586. a.disciplineTo);
  587. } else {
  588. returnValue = FALSE;
  589. }
  590. return returnValue;
  591. }
  592. static int isLegalToBuildCampus(Game g, path destination){
  593. int returnValue = TRUE;
  594. int resourcesToBuildCampus[NUM_DISCIPLINES] = {0, 1, 1, 1, 1, 0};
  595. if(!(isLegalPath(destination))){
  596. returnValue = FALSE;
  597. } else {
  598. if(!((getCampus(g, destination) == VACANT_VERTEX))){
  599. returnValue = FALSE;
  600. }
  601. if(!(playerHasResources(g, resourcesToBuildCampus))){
  602. returnValue = FALSE;
  603. }
  604. if(!(isVertexAdjacentToMyArc(g, destination))){
  605. returnValue = FALSE;
  606. }
  607. if(isVertexAdjacentToCampus(g, destination)){
  608. returnValue = FALSE;
  609. }
  610. }
  611. return returnValue;
  612. }
  613. static int isLegalToBuildGO8(Game g, path destination){
  614. int returnValue = TRUE;
  615. int resourcesToBuildGO8[NUM_DISCIPLINES] = {0, 0, 0, 2, 0, 3};
  616. if(!isLegalPath(destination)){
  617. returnValue = FALSE;
  618. } else {
  619. if(!(getCampus(g, destination) == uniForCurrentPlayer(g))){
  620. returnValue = FALSE;
  621. }
  622. if(!playerHasResources(g, resourcesToBuildGO8)){
  623. returnValue = FALSE;
  624. }
  625. if(!(numGO8s(g) < 8)){
  626. returnValue = FALSE;
  627. }
  628. }
  629. return returnValue;
  630. }
  631. static int isLegalToObtainArc(Game g, path destination){
  632. int returnValue = TRUE;
  633. int resourcesToObtainARC[NUM_DISCIPLINES] = {0, 1, 1, 0, 0, 0};
  634. if(!isLegalPath(destination)){
  635. returnValue = FALSE;
  636. } else {
  637. if(!(getARC(g, destination) == VACANT_ARC)){
  638. returnValue = FALSE;
  639. }
  640. if(!playerHasResources(g, resourcesToObtainARC)){
  641. returnValue = FALSE;
  642. }
  643. if(!isValidArcLocationForPlayer(g, destination)){
  644. returnValue = FALSE;
  645. }
  646. }
  647. return returnValue;
  648. }
  649. static int isLegalToStartSpinoff(Game g){
  650. int returnValue = TRUE;
  651. int resourcesToStartSpinoff[NUM_DISCIPLINES] = {0, 0, 0, 1, 1, 1};
  652. if(!playerHasResources(g, resourcesToStartSpinoff)){
  653. returnValue = FALSE;
  654. }
  655. return returnValue;
  656. }
  657. static int isLegalToRetrainStudents(Game g, int disciplineFrom,
  658. int disciplineTo){
  659. int returnValue = TRUE;
  660. if (disciplineFrom == disciplineTo){
  661. returnValue = FALSE;
  662. }
  663. if (disciplineFrom == STUDENT_THD){
  664. returnValue = FALSE;
  665. }
  666. if (getStudents (g,getWhoseTurn(g), disciplineFrom) <
  667. getExchangeRate(g, getWhoseTurn(g), disciplineFrom, disciplineTo)){
  668. returnValue = FALSE;
  669. }
  670. return returnValue;
  671. }
  672. static int isValidArcLocationForPlayer(Game g, path destination){
  673. int returnValue = FALSE;
  674. if (isEdgeAdjacentToMyCampus(g, destination)){
  675. returnValue = TRUE;
  676. }
  677. if (isEdgeAdjacentToMyEdge(g, destination)){
  678. returnValue = TRUE;
  679. }
  680. return returnValue;
  681. }
  682. static int isEdgeAdjacentToMyCampus(Game g, path destination){
  683. path tempPath;
  684. int returnValue = FALSE;
  685. int player = getWhoseTurn(g);
  686. int myCampus = player;
  687. int length = (int) strlen (destination);
  688. strcpy (tempPath, destination);
  689. tempPath[length] = '\0';
  690. tempPath[length - 1] = 'B';
  691. if(getCampus(g, tempPath) == myCampus){
  692. returnValue = TRUE;
  693. }
  694. if(getCampus(g, destination) == myCampus){
  695. returnValue = TRUE;
  696. }
  697. return returnValue;
  698. }
  699. static int isEdgeAdjacentToMyEdge(Game g, path destination){
  700. printf("%s\n", destination);
  701. int returnValue = FALSE;
  702. path tempPath;
  703. int player = getWhoseTurn(g);
  704. int myARC = player;
  705. int length = (int)strlen (destination);
  706. strcpy (tempPath, destination);
  707. tempPath[length + 1] = '\0';
  708. tempPath[length] = 'R';
  709. if(getARC(g, tempPath) == myARC){
  710. returnValue = TRUE;
  711. }
  712. tempPath[length] = 'L';
  713. if(getARC(g, tempPath) == myARC){
  714. returnValue = TRUE;
  715. }
  716. tempPath[length] = 'B';
  717. tempPath[length + 2] = '\0';
  718. tempPath[length + 1] = 'R';
  719. if(getARC(g, tempPath) == myARC){
  720. returnValue = TRUE;
  721. }
  722. tempPath[length + 1] = 'L';
  723. if(getARC(g, tempPath) == myARC){
  724. returnValue = TRUE;
  725. }
  726. return returnValue;
  727. }
  728. static int isVertexAdjacentToCampus(Game g, path destination){
  729. int returnValue = FALSE;
  730. path tempPath;
  731. int length = (int)strlen (destination);
  732. strcpy (tempPath, destination);
  733. tempPath[length] = '\0';
  734. tempPath[length - 1] = 'R';
  735. if(getCampus(g, tempPath) != VACANT_VERTEX){
  736. returnValue = TRUE;
  737. }
  738. tempPath[length - 1] = 'L';
  739. if(getCampus(g, tempPath) != VACANT_VERTEX){
  740. returnValue = TRUE;
  741. }
  742. if(getCampus(g, tempPath) != VACANT_VERTEX){
  743. returnValue = TRUE;
  744. }
  745. return returnValue;
  746. }
  747. static int isVertexAdjacentToMyArc(Game g, path destination){
  748. int returnValue = FALSE;
  749. path tempPath;
  750. int player = getWhoseTurn(g);
  751. int myARC = player + 1;
  752. int length = (int)strlen (destination);
  753. strcpy (tempPath, destination);
  754. tempPath[length] = '\0';
  755. tempPath[length - 1] = 'R';
  756. if(getARC(g, tempPath) == myARC){
  757. returnValue = TRUE;
  758. }
  759. tempPath[length - 1] = 'L';
  760. if(getARC(g, tempPath) == myARC){
  761. returnValue = TRUE;
  762. }
  763. tempPath[length - 1] = 'B';
  764. if(getARC(g, tempPath) == myARC){
  765. returnValue = TRUE;
  766. }
  767. return returnValue;
  768. }
  769. static int uniForCurrentPlayer(Game g){
  770. return getWhoseTurn(g) +1;
  771. }
  772. static int numGO8s(Game g){
  773. int returnValue = 0;
  774. int i = 0;
  775. while (i < NUM_UNIS){
  776. returnValue += getGO8s (g, i);
  777. i++;
  778. }
  779. return returnValue;
  780. }
  781. static int playerHasResources(Game g, int studentsNeeded[]){
  782. int returnValue = TRUE;
  783. int discipline = 0;
  784. int player = getWhoseTurn(g);
  785. while (discipline < NUM_DISCIPLINES){
  786. if(getStudents (g, player, discipline) < studentsNeeded[discipline]){
  787. returnValue = FALSE;
  788. }
  789. discipline++;
  790. }
  791. return returnValue;
  792. }
  793. static int isLegalPath(path pathToCheck){
  794. int returnValue = TRUE;
  795. path tempPath;
  796. int lengthOfPath = (int)strlen (pathToCheck);
  797. strcpy (tempPath, pathToCheck);
  798. tempPath[lengthOfPath - 1] = '\0';
  799. if (lengthOfPath == 0){
  800. returnValue = TRUE;
  801. } else {
  802. returnValue = (isLegalPath(tempPath) && isOnBoard(pathToCheck));
  803. }
  804. return returnValue;
  805. }
  806. // --- get data about a specified player ---
  807. // return the number of KPI points the specified player currently has
  808. int getKPIpoints (Game g, int player){
  809. int KPIsDueToARCs;
  810. int KPIsDueToCampuses;
  811. int KPIsDueToGO8s;
  812. int KPIsDueToIPs;
  813. int KPIsDueToHavingMostARCs;
  814. int KPIsDueToHavingMostPublications;
  815. int KPIs;
  816. assert ((player > NO_ONE) && (player < UNI_C + 1) );
  817. assert (g != NULL);
  818. KPIsDueToARCs = getARCs (g, player)*2;
  819. KPIsDueToCampuses = getCampuses (g, player)*10;
  820. KPIsDueToGO8s = getGO8s (g, player)*20;
  821. KPIsDueToIPs = getIPs (g, player)*10;
  822. if (getMostARCs(g) == player) {
  823. KPIsDueToHavingMostARCs = 10;
  824. } else {
  825. KPIsDueToHavingMostARCs = 0;
  826. }
  827. if (getMostPublications(g) == player) {
  828. KPIsDueToHavingMostPublications = 10;
  829. } else {
  830. KPIsDueToHavingMostPublications = 0;
  831. }
  832. KPIs = KPIsDueToARCs + KPIsDueToCampuses + KPIsDueToGO8s +
  833. KPIsDueToIPs + KPIsDueToHavingMostARCs +
  834. KPIsDueToHavingMostPublications;
  835. return KPIs;
  836. }
  837. // return the number of ARC grants the specified player currently has
  838. int getARCs (Game g, int player){
  839. assert ((player > NO_ONE) && (player < UNI_C + 1) );
  840. assert (g != NULL);
  841. return g->players[player].ARCs;
  842. }
  843. // return the number of GO8 campuses the specified player currently has
  844. int getGO8s (Game g, int player){
  845. assert ((player > NO_ONE) && (player < UNI_C + 1) );
  846. assert (g != NULL);
  847. return g->players[player].GO8s;
  848. }
  849. // return the number of normal Campuses the specified player currently has
  850. int getCampuses (Game g, int player){
  851. assert ((player > NO_ONE) && (player < UNI_C + 1) );
  852. assert (g != NULL);
  853. return g->players[player].campuses;
  854. }
  855. // return the number of IP Patents the specified player currently has
  856. int getIPs (Game g, int player){
  857. assert ((player > NO_ONE) && (player < UNI_C + 1) );
  858. assert (g != NULL);
  859. return g->players[player].IPs;
  860. }
  861. // return the number of Publications the specified player currently has
  862. int getPublications (Game g, int player){
  863. assert ((player > NO_ONE) && (player < UNI_C + 1) );
  864. assert (g != NULL);
  865. return g->players[player].publications;
  866. }
  867. // return the number of students of the specified discipline type
  868. // the specified player currently has
  869. int getStudents (Game g, int player, int discipline){
  870. assert ((player > NO_ONE) && (player < UNI_C + 1) );
  871. assert (g != NULL);
  872. return g->players[player].students[discipline];
  873. }
  874. // return how many students of discipline type disciplineFrom
  875. // the specified player would need to retrain in order to get one
  876. // student of discipline type disciplineTo. This will depend
  877. // on what retraining centers, if any, they have a campus at.
  878. int getExchangeRate (Game g, int player,
  879. int disciplineFrom, int disciplineTo){
  880. assert ((player > NO_ONE) && (player < UNI_C + 1) );
  881. assert (g != NULL);
  882. return g->players[player].exchangeRate[disciplineFrom][disciplineTo];
  883. }
  884. /* static helper functions that deal with the board */
  885. //static functions for dealing with the board;
  886. //static functions for implementing the Board ADT;
  887. static Board createBoard(void){
  888. Board newBoard;
  889. newBoard = calloc(1, sizeof(*newBoard));
  890. assert(newBoard != NULL);
  891. return newBoard;
  892. }
  893. static void disposeBoard(Board gameBoard){
  894. assert(gameBoard != NULL);
  895. free(gameBoard);
  896. }
  897. static int isOnBoard(path pathToCheck){
  898. vertexSpecifier endOfPathLocation;
  899. int c1, c2, c3, c4, c5, c6;
  900. endOfPathLocation = getVertexSpecifierFromPath(pathToCheck);
  901. c1 = (endOfPathLocation.y+2*endOfPathLocation.x)>= 7;
  902. c2 = (2*endOfPathLocation.y+endOfPathLocation.x)>= 7;
  903. c3 = (endOfPathLocation.y-endOfPathLocation.x) <= 8;
  904. c4 = (2*endOfPathLocation.y + endOfPathLocation.x) <= 23;
  905. c5 = (endOfPathLocation.y+2*endOfPathLocation.x) <= 23;
  906. c6 = (endOfPathLocation.x- endOfPathLocation.y) <= 8;
  907. return c1 && c2 && c3 && c4 && c5 && c6;
  908. }
  909. static vertex getVertex (Board b, vertexSpecifier vertexLocation){
  910. return b->vertexes[vertexLocation.x][vertexLocation.y];
  911. }
  912. static edge getEdge (Board b, edgeSpecifier edgeLocation){
  913. return b->edges[edgeLocation.x][edgeLocation.y];
  914. }
  915. static region getRegion (Board b, regionSpecifier regionLocation){
  916. return b->regions[regionLocation.x][regionLocation.y];
  917. }
  918. static void setVertex (Board b, vertexSpecifier vertexLocation,
  919. vertex vertexContents){
  920. b->vertexes[vertexLocation.x][vertexLocation.y] = vertexContents;
  921. }
  922. static void setEdge (Board b, edgeSpecifier edgeLocation,
  923. edge edgeContents){
  924. b->edges[edgeLocation.x][edgeLocation.y] = edgeContents;
  925. }
  926. static void setRegion (Board b, regionSpecifier regionLocation,
  927. region regionContents){
  928. b->regions[regionLocation.x][regionLocation.y] = regionContents;
  929. }
  930. static edgeSpecifier getEdgeSpecifierFromPath (path edgeLocation){
  931. vertexSpecifier startVertex = {2,10};
  932. vertexSpecifier startbackVertex = {1,11};
  933. vertexSpecifier p1, p2;
  934. edgeSpecifier returnValue;
  935. tracePath(startVertex, startbackVertex,edgeLocation, &p1, &p2);
  936. returnValue.x = p1.x+p2.x;
  937. returnValue.y = p1.y+p2.y;
  938. return returnValue;
  939. }
  940. static vertexSpecifier getVertexSpecifierFromPath (path vertexLocation){
  941. vertexSpecifier startVertex = {2,10};
  942. vertexSpecifier startbackVertex = {1,11};
  943. vertexSpecifier returnValue;
  944. tracePath(startVertex, startbackVertex,vertexLocation, &returnValue, NULL);
  945. return returnValue;
  946. }
  947. static int isPointOnBoard(int row,int col){
  948. return (((row+2*col)>= 7)&& ((2*row+col)>= 7) && ((row-col) <= 8) &&
  949. ((2*row + col) <= 23) && ((row+2*col) <= 23) && ((col- row) <= 8));
  950. }
  951. static edgeSpecifier getEdgeSpecifierFromIndex (int edgeIndex){
  952. edgeSpecifier edges[NUM_EDGES];
  953. (void)getArrayOfEdges(edges);
  954. return edges[edgeIndex];
  955. }
  956. static int getArrayOfEdges(edgeSpecifier edges[]){
  957. int i = 0;
  958. int row = 10;
  959. while(row>=0){
  960. int col=0;
  961. while( col<=10){
  962. if(isVertex(row, col) && isPointOnBoard(row, col)){
  963. if(isVertex(row, col+1) && isPointOnBoard(row, col+1)){
  964. edges[i].x = 2*col + 1;
  965. edges[i].y = 2*row;
  966. i++;
  967. }
  968. if(isVertex(row-1, col) && isPointOnBoard(row-1,col)){
  969. edges[i].x = 2*col;
  970. edges[i].y = 2*row-1;
  971. i++;
  972. }
  973. if(isVertex(row-1,col+1)&& isPointOnBoard(row-1, col+1)){
  974. edges[i].x = 2*col+1;
  975. edges[i].y = 2*row-1;
  976. i++;
  977. }
  978. }
  979. col++;
  980. }
  981. row --;
  982. }
  983. return i;
  984. }
  985. static vertexSpecifier getVertexSpecifierFromIndex (int vertexIndex){
  986. vertexSpecifier points[NUM_VERTECIES];
  987. (void) getArrayOfVertecies(points);
  988. return points[vertexIndex];
  989. }
  990. static int getArrayOfVertecies(vertexSpecifier points[]){
  991. int i = 0;
  992. int row = 10;
  993. while(row>=0){
  994. int col=0;
  995. while( col<=10){
  996. if(isVertex(row, col) && isPointOnBoard(row, col)){
  997. points[i].x = col;
  998. points[i].y = row;
  999. i++;
  1000. }
  1001. col++;
  1002. }
  1003. row --;
  1004. }
  1005. return i;
  1006. }
  1007. static regionSpecifier getRegionSpecifierFromIndex (int regionIndex){
  1008. regionSpecifier regions[NUM_REGIONS];
  1009. regions[0].x = 1;
  1010. regions[0].y = 7;
  1011. regions[1].x = 2;
  1012. regions[1].y = 5;
  1013. regions[2].x = 3;
  1014. regions[2].y = 3;
  1015. regions[3].x = 2;
  1016. regions[3].y = 8;
  1017. regions[4].x = 3;
  1018. regions[4].y = 6;
  1019. regions[5].x = 4;
  1020. regions[5].y = 4;
  1021. regions[6].x = 5;
  1022. regions[6].y = 2;
  1023. regions[7].x = 3;
  1024. regions[7].y = 9;
  1025. regions[8].x = 4;
  1026. regions[8].y = 7;
  1027. regions[9].x = 5;
  1028. regions[9].y = 5;
  1029. regions[10].x = 6;
  1030. regions[10].y = 3;
  1031. regions[11].x = 7;
  1032. regions[11].y = 1;
  1033. regions[12].x = 5;
  1034. regions[12].y = 8;
  1035. regions[13].x = 6;
  1036. regions[13].y = 6;
  1037. regions[14].x = 7;
  1038. regions[14].y = 4;
  1039. regions[15].x = 8;
  1040. regions[15].y = 2;
  1041. regions[16].x = 7;
  1042. regions[16].y = 7;
  1043. regions[17].x = 8;
  1044. regions[17].y = 5;
  1045. regions[18].x = 9;
  1046. regions[18].y = 3;
  1047. return regions[regionIndex];
  1048. }
  1049. static int isNextToRetrainingCenter(Board g, vertexSpecifier vertexNo){
  1050. int returnValue = FALSE;
  1051. int i;
  1052. vertexSpecifier regionsThatAre[18];
  1053. regionsThatAre[0].x = 1;
  1054. regionsThatAre[0].y = 9;
  1055. regionsThatAre[1].x = 2;
  1056. regionsThatAre[1].y = 9;
  1057. regionsThatAre[2].x = 4;
  1058. regionsThatAre[2].y = 9;
  1059. regionsThatAre[3].x = 5;
  1060. regionsThatAre[3].y = 9;
  1061. regionsThatAre[4].x = 0;
  1062. regionsThatAre[4].y = 8;
  1063. regionsThatAre[5].x = 0;
  1064. regionsThatAre[5].y = 7;
  1065. regionsThatAre[6].x = 7;
  1066. regionsThatAre[6].y = 8;
  1067. regionsThatAre[7].x = 8;
  1068. regionsThatAre[7].y = 7;
  1069. regionsThatAre[8].x = 1;
  1070. regionsThatAre[8].y = 5;
  1071. regionsThatAre[9].x = 2;
  1072. regionsThatAre[9].y = 4;
  1073. regionsThatAre[10].x = 9;
  1074. regionsThatAre[10].y = 5;
  1075. regionsThatAre[11].x = 8;
  1076. regionsThatAre[11].y = 4;
  1077. regionsThatAre[12].x = 4;
  1078. regionsThatAre[12].y = 2;
  1079. regionsThatAre[13].x = 5;
  1080. regionsThatAre[13].y = 1;
  1081. regionsThatAre[14].x = 9;
  1082. regionsThatAre[14].y = 2;
  1083. regionsThatAre[15].x = 9;
  1084. regionsThatAre[15].y = 1;
  1085. regionsThatAre[16].x = 7;
  1086. regionsThatAre[16].y = 0;
  1087. regionsThatAre[17].x = 8;
  1088. regionsThatAre[17].y = 0;
  1089. i = 0;
  1090. while (i<18){
  1091. if((vertexNo.x == regionsThatAre[i].x) &&
  1092. (vertexNo.y == regionsThatAre[i].y)){
  1093. returnValue = TRUE;
  1094. }
  1095. i++;
  1096. }
  1097. return returnValue;
  1098. }
  1099. static int getRetrainingCenterType(Board g, vertexSpecifier vertexNo){
  1100. int retrainingCenters[11][11] = {{0}};
  1101. int returnValue;
  1102. retrainingCenters[1][9] = STUDENT_MTV;
  1103. retrainingCenters[2][9] = STUDENT_MTV;
  1104. retrainingCenters[4][9] = STUDENT_MMONEY;
  1105. retrainingCenters[5][9] = STUDENT_MMONEY;
  1106. retrainingCenters[0][8] = GENERAL_RC;
  1107. retrainingCenters[0][7] = GENERAL_RC;
  1108. retrainingCenters[7][8] = GENERAL_RC;
  1109. retrainingCenters[8][7] = GENERAL_RC;
  1110. retrainingCenters[1][5] = GENERAL_RC;
  1111. retrainingCenters[2][4] = GENERAL_RC;
  1112. retrainingCenters[9][5] = STUDENT_BQN;
  1113. retrainingCenters[8][4] = STUDENT_BQN;
  1114. retrainingCenters[4][2] = STUDENT_BPS;
  1115. retrainingCenters[5][1] = STUDENT_BPS;
  1116. retrainingCenters[9][2] = STUDENT_MJ;
  1117. retrainingCenters[9][1] = STUDENT_MJ;
  1118. retrainingCenters[7][0] = GENERAL_RC;
  1119. retrainingCenters[8][0] = GENERAL_RC;
  1120. returnValue = retrainingCenters[vertexNo.x][vertexNo.y];
  1121. return returnValue;
  1122. }
  1123. static vertexSpecifier getSpecifierOfSpecialVertex(int specialLocation){
  1124. int specialPointArray[6] = {0, 6, 42, 53, 41, 11};
  1125. vertexSpecifier a;
  1126. a= getVertexSpecifierFromIndex (specialPointArray[specialLocation]);
  1127. return a;
  1128. }
  1129. static edgeSpecifier getSpecifierOfSpecialEdge(int SpecialLocation){
  1130. int specialEdgeArray[6] = {1, 18, 60, 70, 51, 15};
  1131. edgeSpecifier a;
  1132. a= getEdgeSpecifierFromIndex (specialEdgeArray[SpecialLocation]);
  1133. return a;
  1134. }
  1135. static vertexSpecifier getVertexAdjacentToRegion (regionSpecifier input,
  1136. int index){
  1137. vertexSpecifier vertexAdjacentToRegion;
  1138. if (index == 0){
  1139. vertexAdjacentToRegion.x = input.x;
  1140. vertexAdjacentToRegion.y = input.y + 1;
  1141. } else if (index == 1){
  1142. vertexAdjacentToRegion.x = input.x + 1;
  1143. vertexAdjacentToRegion.y = input.y;
  1144. } else if (index == 2){
  1145. vertexAdjacentToRegion.x = input.x + 1;
  1146. vertexAdjacentToRegion.y = input.y - 1;
  1147. } else if (index == 3){
  1148. vertexAdjacentToRegion.x = input.x;
  1149. vertexAdjacentToRegion.y = input.y - 1;
  1150. } else if (index == 4){
  1151. vertexAdjacentToRegion.x = input.x - 1;
  1152. vertexAdjacentToRegion.y = input.y;
  1153. } else if (index == 5){
  1154. vertexAdjacentToRegion.x = input.x - 1;
  1155. vertexAdjacentToRegion.y = input.y + 1;
  1156. } else {
  1157. vertexAdjacentToRegion.x = 0;
  1158. vertexAdjacentToRegion.y = 0;
  1159. assert(FALSE);
  1160. }
  1161. return vertexAdjacentToRegion;
  1162. }
  1163. static vertexSpecifier getRightVertex(vertexSpecifier current,
  1164. vertexSpecifier back){
  1165. int backcount=0;
  1166. int i=0;
  1167. vertexSpecifier surroundingVertecies[3];
  1168. getSurroundingVertecies(current, surroundingVertecies);
  1169. while(i<3){
  1170. if((surroundingVertecies[i].x == back.x) && (surroundingVertecies[i].y == back.y)){
  1171. backcount = i;
  1172. }
  1173. i++;
  1174. }
  1175. return surroundingVertecies[(backcount+2)%3];
  1176. }
  1177. static vertexSpecifier getLeftVertex(vertexSpecifier current,
  1178. vertexSpecifier back){
  1179. int backcount = 0;
  1180. int i=0;
  1181. vertexSpecifier surroundingVertecies[3];
  1182. getSurroundingVertecies(current, surroundingVertecies);
  1183. while(i<3){
  1184. if((surroundingVertecies[i].x == back.x) && (surroundingVertecies[i].y == back.y)){
  1185. backcount = i;
  1186. }
  1187. i++;
  1188. }
  1189. return surroundingVertecies[(backcount+1)%3];
  1190. }
  1191. static void getSurroundingVertecies(vertexSpecifier p1,
  1192. vertexSpecifier surroundingVertecies[3]){
  1193. int i = 0;
  1194. if(isVertex(p1.x,p1.y+1)){
  1195. vertexSpecifier temp = {p1.x, p1.y +1};
  1196. surroundingVertecies[i] = temp;
  1197. i++;
  1198. }
  1199. if(isVertex(p1.x+1,p1.y)){
  1200. vertexSpecifier temp = {p1.x+1, p1.y};
  1201. surroundingVertecies[i] = temp;
  1202. i++;
  1203. }
  1204. if(isVertex(p1.x+1,p1.y-1)){
  1205. vertexSpecifier temp = {p1.x+1, p1.y -1};
  1206. surroundingVertecies[i] = temp;
  1207. i++;
  1208. }
  1209. if(isVertex(p1.x,p1.y-1)){
  1210. vertexSpecifier temp = {p1.x, p1.y-1};
  1211. surroundingVertecies[i] = temp;
  1212. i++;
  1213. }
  1214. if(isVertex(p1.x-1,p1.y)){
  1215. vertexSpecifier temp = {p1.x-1, p1.y};
  1216. surroundingVertecies[i] = temp;
  1217. i++;
  1218. }
  1219. if(isVertex(p1.x-1,p1.y+1)){
  1220. vertexSpecifier temp = {p1.x-1, p1.y+1};
  1221. surroundingVertecies[i] = temp;
  1222. i++;
  1223. }
  1224. }
  1225. static int isVertex(int x, int y){
  1226. return ((y - x)%3 != 0);
  1227. }
  1228. static void tracePath(vertexSpecifier start, vertexSpecifier back,
  1229. path input, vertexSpecifier* p1, vertexSpecifier* p2){
  1230. vertexSpecifier currentNode = start;
  1231. vertexSpecifier currentBackDirection = back;
  1232. vertexSpecifier temp;
  1233. int i;
  1234. i=0;
  1235. while (input[i] != '\0'){
  1236. temp = currentNode;
  1237. if (input[i] == 'L'){
  1238. currentNode = getLeftVertex (currentNode, currentBackDirection);
  1239. currentBackDirection = temp;
  1240. } else if (input[i] == 'R'){
  1241. currentNode = getRightVertex (currentNode, currentBackDirection);
  1242. currentBackDirection = temp;
  1243. } else if (input[i] == 'B'){
  1244. currentNode = currentBackDirection;
  1245. currentBackDirection = temp;
  1246. }
  1247. i++;
  1248. }
  1249. if(p1 != NULL){
  1250. *p1 = currentNode;
  1251. }
  1252. if(p2 != NULL){
  1253. *p2 = currentBackDirection;
  1254. }
  1255. }