Advertisement
Guest User

mk2 match generator

a guest
Jun 25th, 2016
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.54 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #include <stdio.h>
  6.  
  7. typedef struct tag_fighter{
  8. struct tag_fighter *next;
  9. char *name;
  10. unsigned int fighter_ID;
  11. unsigned int used_within_12;
  12. unsigned int p2_used_within_12;
  13. }FIGHTER;
  14.  
  15. FIGHTER *root = NULL;
  16.  
  17. #define MATCH_STRING 100
  18. #define NUM_OF_FIGHTERS 12
  19. #define YES 1
  20. #define NO 0
  21.  
  22. void create_fighter(char *fighter_name, unsigned int ID, unsigned int used_within_12, unsigned int p2_used_within_12);
  23. FIGHTER *fetch_fighter(FIGHTER *root, unsigned int player);
  24. int get_match(char match[], int size);
  25. int get_matches(char *matches[], int num_of_fights);
  26. void create_all_fighters(void);
  27. blank_array(char *matches[]);
  28. int test_combos();
  29. void parse_match(char *matches, char *s, char *t);
  30. int set_match_conditions(int mirror_matches, char *exclusion_list[]);
  31. char *strdup_(char *s);
  32.  
  33. int main(int argc, char *argv[])
  34. {
  35. int i;
  36. char *exclusion_list[100];
  37. char match[30];
  38. set_match_conditions(YES, NULL);
  39.  
  40. for (i = 1; get_match(match, 30); i++)
  41. printf("%d.) %s\n", i, match);
  42.  
  43. set_match_conditions(NO, NULL); //set mirror matches to NO
  44. putchar('\n');
  45. printf("SET WITH NO MIRROR MATCHES:\n\n");
  46. for (i = 1; get_match(match, 30); i++)
  47. printf("%d.) %s\n", i, match);
  48.  
  49. getch();
  50. return 0;
  51. }
  52.  
  53. static int mirrors;
  54. char *exclusion_list[100];
  55. static int match_conditions;
  56. static int array_state;
  57. static int num_of_fights;
  58. static int created_fighters;
  59.  
  60. #define FULL 1
  61. #define EMPTY 0
  62. #define MATCHSIZE 30
  63. int mark_mirror_combos(void);
  64. int unmark_all_combos(void);
  65.  
  66. int set_match_conditions(int mirror_matches, char *exclusion_list[])//function will reset existing matches when called again - note: exclusion list not used, left there to be implemented later
  67. {
  68.  
  69. if (mirror_matches != 0 && mirror_matches != 1){
  70. mirrors = -1; //invalid argument given
  71. return 0; //returns 0 if something is wrong
  72. }
  73. if (created_fighters != YES){ //create fighter list only on the first time in
  74. create_all_fighters();
  75. created_fighters = YES;
  76. }
  77.  
  78. unmark_all_combos();
  79. srand(time(NULL));
  80.  
  81. if (mirror_matches == 0){ //no mirror matches
  82. mark_mirror_combos();
  83. mirrors = NO;
  84. num_of_fights = 132;
  85. }
  86. else{
  87. mirrors = YES;
  88. num_of_fights = 144;
  89. }
  90.  
  91. match_conditions = 1; //let's us know this function has been called
  92. array_state = EMPTY; //state is always EMPTY once this is called
  93.  
  94. return 1;
  95. }
  96.  
  97. int get_match(char match[], int size) //function will not work if mirrors variable is invalid
  98. {
  99. static char *matches[144];
  100. static int i;
  101. int return_value;
  102.  
  103. if (mirrors == -1 || match_conditions != 1 || size < 30) //mirrors is invalid or match_conditions was not called
  104. return 0;
  105.  
  106. if (array_state == FULL){ //we need to increment i b4 returning bc we can't do it afterwards to get to the next string, so we do match[i-1] for return statement
  107. while(i++ < num_of_fights){
  108. strncpy(match, matches[i-1], size); //returns a pointer to a string (which match[i] is, a pointer to a string)
  109. free(matches[i-1]);
  110. return 1;
  111. }
  112. array_state = EMPTY;
  113. i = match_conditions = 0; //set_match_conditions must be called again b4 get_match can be called again
  114. return 0;
  115. }
  116.  
  117. get_matches(matches, num_of_fights);
  118. array_state = FULL;
  119. return_value = get_match(match, size);
  120.  
  121. return return_value;
  122. }
  123.  
  124. blank_array(char *matches[])
  125. {
  126. int j;
  127. for (j = 0; j < num_of_fights; j++)
  128. matches[j] = 0;
  129. }
  130. #define PLAYER1 1
  131. #define PLAYER2 2
  132. static int fighter_count, fighter_count2 = 0;
  133.  
  134. int mark_combo(int x, int y);
  135. int check_all_combos(void);
  136. int check_combo(int x, int y); //returns 1 if combo exists, returns 0 if combo does not exist
  137. void unmark_combos(char *matches[], int fighter_count, int match_count);
  138. void clear_12_matches(char *matches[], int *fighter_count, int *fighter_count2, int *match_count);
  139. void restore_fighter_uses(FIGHTER *root, unsigned int player); //change this to restore both player fighter uses and accept &fighter_counts as only args to reset counters
  140.  
  141. int get_matches(char *matches[], int num_of_fights)
  142. {
  143. FIGHTER *p1, *p2;
  144. int match_count = 0, match_occurred;
  145.  
  146. blank_array(matches); //every call will result in blanking of array, array itself should be passed from get_match
  147.  
  148. while (match_count < num_of_fights){
  149. while (fighter_count < NUM_OF_FIGHTERS){ //string_count can be replaced with fighter_count or match_count % 12 == 0
  150.  
  151. p1 = fetch_fighter(root, PLAYER1);
  152. p2 = fetch_fighter(root, PLAYER2);
  153.  
  154. while ((match_occurred = check_combo(p1->fighter_ID, p2->fighter_ID)) == 1 && match_count < num_of_fights){ //while the match exists AND # of fights has not reached limit, find a new match
  155. p1->used_within_12 = NO; //erase this and put
  156. fighter_count--;
  157. p1 = fetch_fighter(root, PLAYER1); //FIX MEEEE
  158. p2->p2_used_within_12 = NO; //the following here: previous_char->used_within_12 = NO, this would speed it up, but require more work bc chars can run out and loop would run forever
  159. fighter_count2--;
  160. p2 = fetch_fighter(root, PLAYER2);
  161. }
  162.  
  163. if (match_occurred == NO){ //check_combo is 0 if match has not occurred //THIS MUST BE CORRECT TOO, IF MATCHES REACH A CERTAIN POINT AND MUST BE ERASED, maybe we can save variable above and use it here instead of calc get_combo again
  164. mark_combo(p1->fighter_ID, p2->fighter_ID);
  165. if (matches[match_count] == NULL)
  166. matches[match_count] = malloc(30*sizeof(char));
  167. sprintf(matches[match_count++], "%s Vs %s", p1->name, p2->name);
  168. }
  169.  
  170. if (fighter_count != 12 && check_all_combos() ){ //make sure all possible matches have not been exhuasted given the fighters left
  171. unmark_combos(matches, fighter_count, match_count);
  172. clear_12_matches(matches, &fighter_count, &fighter_count2, &match_count);
  173. //clear relevant match strings from match[] and reset counters
  174. }
  175.  
  176. }//END OF 12 LOOP
  177. restore_fighter_uses(root, PLAYER1);
  178. restore_fighter_uses(root, PLAYER2);
  179. fighter_count = fighter_count2 = 0;
  180. }//END OF 144 LOOP
  181.  
  182. return 1; //144 matches successfully saved
  183. }
  184. FIGHTER *fetch_fighter(FIGHTER *root, unsigned int player) //code is basically the same for PLAYER1 and PLAYER2
  185. {
  186. int x;
  187. FIGHTER *fp = root; //fighter pointer
  188.  
  189. x = 1 + (rand() % (NUM_OF_FIGHTERS)); //get next player ID
  190.  
  191. if (player == PLAYER1){
  192. while (x != fp->fighter_ID)
  193. fp = fp->next;
  194.  
  195. while (fp->used_within_12 == YES && fighter_count < NUM_OF_FIGHTERS){ //while the fighter has been used within the last 12 matches, get a new fighter
  196. x = 1 + (rand() % (NUM_OF_FIGHTERS));
  197. fp = root;
  198. while (x != fp->fighter_ID)
  199. fp = fp->next;
  200. }
  201. if (fighter_count == NUM_OF_FIGHTERS){
  202. fighter_count = 0;
  203. restore_fighter_uses(root, player);
  204. fp = fetch_fighter(root, player);
  205. }
  206. else if (fighter_count != NUM_OF_FIGHTERS){ //mark fighter as having being used within last 12
  207. fp->used_within_12 = YES;
  208. fighter_count++;
  209. }
  210. }
  211.  
  212. else if (player == PLAYER2){
  213. while (x != fp->fighter_ID)
  214. fp = fp->next;
  215. //printf("PLAYER 2 Fighter count: %d\n", count);
  216. while (fp->p2_used_within_12 == YES && fighter_count2 < NUM_OF_FIGHTERS){ //while the match has been played within last 12 matches, get a new fighter
  217. x = 1 + (rand() % (NUM_OF_FIGHTERS));
  218. fp = root;
  219. while (x != fp->fighter_ID)
  220. fp = fp->next;
  221.  
  222. }
  223. if (fighter_count2 == NUM_OF_FIGHTERS){
  224. fighter_count2 = 0;
  225. restore_fighter_uses(root, player);
  226. fp = fetch_fighter(root, player);
  227. }
  228. else if (fighter_count2 != NUM_OF_FIGHTERS){ //mark fighter as having being used within last 12
  229. fp->p2_used_within_12 = YES;
  230. fighter_count2++;
  231. }
  232. }
  233.  
  234. return fp;
  235. }
  236.  
  237. void restore_fighter_uses(FIGHTER *root, unsigned int player)
  238. {
  239. FIGHTER *fp;
  240.  
  241. for (fp = root; fp != NULL; fp = fp->next)
  242. if (player == PLAYER1)
  243. fp->used_within_12 = NO;
  244. else
  245. fp->p2_used_within_12 = NO;
  246. }
  247.  
  248. void clear_12_matches(char *matches[], int *fighter_count, int *fighter_count2, int *match_count) //clear relevant match strings from match[] and reset counters
  249. {
  250. int loop_count = *fighter_count - 1;
  251. (*match_count)--;
  252.  
  253. while (loop_count > 0){ //fighter_count == fighter_count2, can use either one for this loop
  254. matches[*match_count] = 0;
  255. loop_count--;
  256. (*match_count)--;
  257. }
  258.  
  259. matches[*match_count] = 0;
  260. *fighter_count = *fighter_count2 = 0;
  261.  
  262. restore_fighter_uses(root, PLAYER1);
  263. restore_fighter_uses(root, PLAYER2);
  264. }
  265.  
  266.  
  267. int calc_remain_matches(void);
  268. static unsigned int combotab[144];
  269. #define FORMULA(x, y) ((x - 1) * 12 + y - 1)
  270.  
  271. int check_combo(int x, int y)//returns 1 if combo exists, returns 0 if combo does not exist
  272. {
  273. if(combotab[FORMULA(x, y)] == YES)
  274. return 1;
  275. else
  276. return 0;
  277. }
  278.  
  279. int check_all_combos(void) //return 0 if there is at least 1 match left -- return 1 if there are matches left to be played
  280. {
  281. FIGHTER *p, *p2;
  282.  
  283. for (p = root; p != NULL ; p = p->next){
  284. while (p != NULL && p->used_within_12 != NO)
  285. p = p->next;
  286.  
  287. if (p == NULL)
  288. break;//?
  289. for(p2 = root; p2 != NULL; p2 = p2->next){
  290. while(p2 != NULL && p2->p2_used_within_12 != NO)
  291. p2 = p2->next;
  292.  
  293. if (p2 != NULL){
  294. if (combotab[FORMULA(p->fighter_ID, p2->fighter_ID)] == NO)
  295. return 0; //still a match left -- don't clear
  296. }
  297. else if (p2 == NULL)
  298. break; //clear
  299. }
  300. }
  301. return 1; //all possible matches have occurred, clear match counts
  302. }
  303.  
  304. int mark_combo(int x, int y) //mark one combo
  305. {
  306. if (combotab[FORMULA(x, y)] == YES){ //it's already yes somehow
  307. perror("Error: Mark Combo function is not working properly\n");
  308. getchar();
  309. exit(1);
  310. }
  311.  
  312. combotab[FORMULA(x, y)] = YES;
  313. return 1;
  314. }
  315. int mark_mirror_combos(void) //marks mirror combos as having been used - this occurrs when user requests no mirror matches, total of 132 matches in that case
  316. {
  317. int i, y;
  318. for(i = y = 1; i <= 12; i++, y++)
  319. if (combotab[FORMULA(i, y)] == YES){ //it's already yes somehow
  320. perror("Error: Mark mirror combo function is not working properly\n");
  321. getchar();
  322. exit(1);
  323. }
  324. else
  325. combotab[FORMULA(i, y)] = YES;
  326. return 1;
  327. }
  328. void parse_match(char *match, char *s, char *t);
  329. void find_IDs(char *name, char *name2, int *ID, int *ID2);
  330.  
  331. void unmark_combos(char *matches[], int fighter_count, int match_count) //unmarks 12 matches from combotab[]
  332. {
  333. int ID, ID2, i;
  334. char name[20], name2[20];
  335.  
  336. for (match_count--; fighter_count > 0; match_count--, fighter_count--){
  337. parse_match(matches[match_count], name, name2); //stores fighter names from match into names
  338. find_IDs(name, name2, &ID, &ID2); //gets ID's based on the names
  339. combotab[FORMULA(ID, ID2)] = NO; //unmarks match
  340. }
  341.  
  342. }
  343. void parse_match(char *match, char *s, char *t)
  344. {
  345. int i, j;
  346. for (i = 0; match[i] != 'V'; i++)
  347. s[i] = match[i];
  348. s[i-1] = '\0';
  349. i += 3;
  350. for (j = 0; match[i] != '\0'; i++)
  351. t[j++] = match[i];
  352. t[j] = '\0';
  353. }
  354. void find_IDs(char *name, char *name2, int *ID, int *ID2)
  355. {
  356. FIGHTER *p = root;
  357.  
  358. while (p != NULL && strcmp(p->name, name) != 0)
  359. p = p->next;
  360. if (p == NULL){
  361. perror("ERROR");
  362. exit(1);
  363. }
  364. *ID = p->fighter_ID;
  365.  
  366. for (p = root; p != NULL && strcmp(p->name, name2) != 0; p = p->next)
  367. ;
  368. if (p == NULL){
  369. perror("ERROR in FIND_IDS: Fighter pointer is NULL\n");
  370. exit(1);
  371. }
  372. *ID2 = p->fighter_ID;
  373. }
  374. int unmark_all_combos(void)
  375. {
  376. int i;
  377. for (i = 0; i < 144; i++)
  378. combotab[i] = NO;
  379. }
  380.  
  381. void error_code(void){
  382. perror("ERROR: Not enough space to create name\n");
  383. getch();
  384. exit(1);
  385. }
  386.  
  387. void create_all_fighters(void){
  388.  
  389. create_fighter("Liu Kang", 1, 0, 0);
  390. create_fighter("Kung Lao", 2, 0, 0);
  391. create_fighter("Johnny Cage", 3, 0, 0);
  392. create_fighter("Reptile", 4, 0, 0);
  393. create_fighter("Sub-Zero", 5, 0, 0);
  394. create_fighter("Shang Tsung", 6, 0, 0);
  395. create_fighter("Kitana", 7, 0, 0);
  396. create_fighter("Jax", 8, 0, 0);
  397. create_fighter("Mileena", 9, 0, 0);
  398. create_fighter("Baraka", 10, 0, 0);
  399. create_fighter("Scorpion", 11, 0, 0);
  400. create_fighter("Raiden", 12, 0, 0);
  401. }
  402.  
  403. void create_fighter(char *fighter_name, unsigned int ID, unsigned int used_within_12, unsigned int p2_used_within_12) //creates a linked list of characters in order of appearence
  404. {
  405. FIGHTER *np, *npp;
  406. npp = NULL;
  407. for (np = root; np != NULL; np = np->next)
  408. npp = np; //npp will always be the list block before np (np will be NULL tho once np->next finds end of list) once this loop breaks, if root is NULL, npp == np
  409.  
  410. np = (FIGHTER *)malloc(sizeof *np);
  411. if (np == NULL)
  412. error_code();
  413. np->next = NULL;
  414. np->name = strdup_(fighter_name);
  415. np->fighter_ID = ID;
  416. np->used_within_12 = used_within_12;
  417. np->p2_used_within_12 = used_within_12;
  418.  
  419. if (root != NULL)
  420. npp->next = np; //npp is block before final block, np is final block - (note: no storage allocation needed, pointing to storage already allocated and with stored data)
  421.  
  422. if (root == NULL){ // if root doesn't point to first fighter, point to it
  423. root = np; //no storage allocation needed, pointing to storage already allocated and with stored data
  424. }
  425. }
  426.  
  427. char *strdup_(char *s) //function defined in K&R
  428. {
  429. char *p;
  430.  
  431. p = (char *)malloc(strlen(s) + 1); // +1 for '\0' character //always allocates space the size of s for p, so no need for strncpy() below
  432. if (p != NULL)
  433. strcpy(p, s);
  434. else
  435. error_code();
  436. return p;
  437. }
  438.  
  439.  
  440. /*
  441. static int i = 1;
  442. int j, count, dupl = 0;
  443. char one_match[20];
  444.  
  445. for (i = 0; i < 144; i++){
  446. strcpy(one_match, match[i]);
  447. count = 0;
  448. for (j = 0; j < 144; j++){
  449. if (strcmp(match[j], one_match) == 0)
  450. count++;
  451. if (count == 2){
  452. printf("Error, duplicate match found! :(\n");
  453. count = 0;
  454. }
  455. }
  456. }
  457. printf("No duplicates found\n", dupl);
  458. getch();
  459. return 0;
  460. }
  461. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement