Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- #include <stdio.h>
- typedef struct tag_fighter{
- struct tag_fighter *next;
- char *name;
- unsigned int fighter_ID;
- unsigned int used_within_12;
- unsigned int p2_used_within_12;
- }FIGHTER;
- FIGHTER *root = NULL;
- #define MATCH_STRING 100
- #define NUM_OF_FIGHTERS 12
- #define YES 1
- #define NO 0
- void create_fighter(char *fighter_name, unsigned int ID, unsigned int used_within_12, unsigned int p2_used_within_12);
- FIGHTER *fetch_fighter(FIGHTER *root, unsigned int player);
- int get_match(char match[], int size);
- int get_matches(char *matches[], int num_of_fights);
- void create_all_fighters(void);
- blank_array(char *matches[]);
- int test_combos();
- void parse_match(char *matches, char *s, char *t);
- int set_match_conditions(int mirror_matches, char *exclusion_list[]);
- char *strdup_(char *s);
- int main(int argc, char *argv[])
- {
- int i;
- char *exclusion_list[100];
- char match[30];
- set_match_conditions(YES, NULL);
- for (i = 1; get_match(match, 30); i++)
- printf("%d.) %s\n", i, match);
- set_match_conditions(NO, NULL); //set mirror matches to NO
- putchar('\n');
- printf("SET WITH NO MIRROR MATCHES:\n\n");
- for (i = 1; get_match(match, 30); i++)
- printf("%d.) %s\n", i, match);
- getch();
- return 0;
- }
- static int mirrors;
- char *exclusion_list[100];
- static int match_conditions;
- static int array_state;
- static int num_of_fights;
- static int created_fighters;
- #define FULL 1
- #define EMPTY 0
- #define MATCHSIZE 30
- int mark_mirror_combos(void);
- int unmark_all_combos(void);
- 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
- {
- if (mirror_matches != 0 && mirror_matches != 1){
- mirrors = -1; //invalid argument given
- return 0; //returns 0 if something is wrong
- }
- if (created_fighters != YES){ //create fighter list only on the first time in
- create_all_fighters();
- created_fighters = YES;
- }
- unmark_all_combos();
- srand(time(NULL));
- if (mirror_matches == 0){ //no mirror matches
- mark_mirror_combos();
- mirrors = NO;
- num_of_fights = 132;
- }
- else{
- mirrors = YES;
- num_of_fights = 144;
- }
- match_conditions = 1; //let's us know this function has been called
- array_state = EMPTY; //state is always EMPTY once this is called
- return 1;
- }
- int get_match(char match[], int size) //function will not work if mirrors variable is invalid
- {
- static char *matches[144];
- static int i;
- int return_value;
- if (mirrors == -1 || match_conditions != 1 || size < 30) //mirrors is invalid or match_conditions was not called
- return 0;
- 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
- while(i++ < num_of_fights){
- strncpy(match, matches[i-1], size); //returns a pointer to a string (which match[i] is, a pointer to a string)
- free(matches[i-1]);
- return 1;
- }
- array_state = EMPTY;
- i = match_conditions = 0; //set_match_conditions must be called again b4 get_match can be called again
- return 0;
- }
- get_matches(matches, num_of_fights);
- array_state = FULL;
- return_value = get_match(match, size);
- return return_value;
- }
- blank_array(char *matches[])
- {
- int j;
- for (j = 0; j < num_of_fights; j++)
- matches[j] = 0;
- }
- #define PLAYER1 1
- #define PLAYER2 2
- static int fighter_count, fighter_count2 = 0;
- int mark_combo(int x, int y);
- int check_all_combos(void);
- int check_combo(int x, int y); //returns 1 if combo exists, returns 0 if combo does not exist
- void unmark_combos(char *matches[], int fighter_count, int match_count);
- void clear_12_matches(char *matches[], int *fighter_count, int *fighter_count2, int *match_count);
- 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
- int get_matches(char *matches[], int num_of_fights)
- {
- FIGHTER *p1, *p2;
- int match_count = 0, match_occurred;
- blank_array(matches); //every call will result in blanking of array, array itself should be passed from get_match
- while (match_count < num_of_fights){
- while (fighter_count < NUM_OF_FIGHTERS){ //string_count can be replaced with fighter_count or match_count % 12 == 0
- p1 = fetch_fighter(root, PLAYER1);
- p2 = fetch_fighter(root, PLAYER2);
- 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
- p1->used_within_12 = NO; //erase this and put
- fighter_count--;
- p1 = fetch_fighter(root, PLAYER1); //FIX MEEEE
- 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
- fighter_count2--;
- p2 = fetch_fighter(root, PLAYER2);
- }
- 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
- mark_combo(p1->fighter_ID, p2->fighter_ID);
- if (matches[match_count] == NULL)
- matches[match_count] = malloc(30*sizeof(char));
- sprintf(matches[match_count++], "%s Vs %s", p1->name, p2->name);
- }
- if (fighter_count != 12 && check_all_combos() ){ //make sure all possible matches have not been exhuasted given the fighters left
- unmark_combos(matches, fighter_count, match_count);
- clear_12_matches(matches, &fighter_count, &fighter_count2, &match_count);
- //clear relevant match strings from match[] and reset counters
- }
- }//END OF 12 LOOP
- restore_fighter_uses(root, PLAYER1);
- restore_fighter_uses(root, PLAYER2);
- fighter_count = fighter_count2 = 0;
- }//END OF 144 LOOP
- return 1; //144 matches successfully saved
- }
- FIGHTER *fetch_fighter(FIGHTER *root, unsigned int player) //code is basically the same for PLAYER1 and PLAYER2
- {
- int x;
- FIGHTER *fp = root; //fighter pointer
- x = 1 + (rand() % (NUM_OF_FIGHTERS)); //get next player ID
- if (player == PLAYER1){
- while (x != fp->fighter_ID)
- fp = fp->next;
- 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
- x = 1 + (rand() % (NUM_OF_FIGHTERS));
- fp = root;
- while (x != fp->fighter_ID)
- fp = fp->next;
- }
- if (fighter_count == NUM_OF_FIGHTERS){
- fighter_count = 0;
- restore_fighter_uses(root, player);
- fp = fetch_fighter(root, player);
- }
- else if (fighter_count != NUM_OF_FIGHTERS){ //mark fighter as having being used within last 12
- fp->used_within_12 = YES;
- fighter_count++;
- }
- }
- else if (player == PLAYER2){
- while (x != fp->fighter_ID)
- fp = fp->next;
- //printf("PLAYER 2 Fighter count: %d\n", count);
- 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
- x = 1 + (rand() % (NUM_OF_FIGHTERS));
- fp = root;
- while (x != fp->fighter_ID)
- fp = fp->next;
- }
- if (fighter_count2 == NUM_OF_FIGHTERS){
- fighter_count2 = 0;
- restore_fighter_uses(root, player);
- fp = fetch_fighter(root, player);
- }
- else if (fighter_count2 != NUM_OF_FIGHTERS){ //mark fighter as having being used within last 12
- fp->p2_used_within_12 = YES;
- fighter_count2++;
- }
- }
- return fp;
- }
- void restore_fighter_uses(FIGHTER *root, unsigned int player)
- {
- FIGHTER *fp;
- for (fp = root; fp != NULL; fp = fp->next)
- if (player == PLAYER1)
- fp->used_within_12 = NO;
- else
- fp->p2_used_within_12 = NO;
- }
- void clear_12_matches(char *matches[], int *fighter_count, int *fighter_count2, int *match_count) //clear relevant match strings from match[] and reset counters
- {
- int loop_count = *fighter_count - 1;
- (*match_count)--;
- while (loop_count > 0){ //fighter_count == fighter_count2, can use either one for this loop
- matches[*match_count] = 0;
- loop_count--;
- (*match_count)--;
- }
- matches[*match_count] = 0;
- *fighter_count = *fighter_count2 = 0;
- restore_fighter_uses(root, PLAYER1);
- restore_fighter_uses(root, PLAYER2);
- }
- int calc_remain_matches(void);
- static unsigned int combotab[144];
- #define FORMULA(x, y) ((x - 1) * 12 + y - 1)
- int check_combo(int x, int y)//returns 1 if combo exists, returns 0 if combo does not exist
- {
- if(combotab[FORMULA(x, y)] == YES)
- return 1;
- else
- return 0;
- }
- 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
- {
- FIGHTER *p, *p2;
- for (p = root; p != NULL ; p = p->next){
- while (p != NULL && p->used_within_12 != NO)
- p = p->next;
- if (p == NULL)
- break;//?
- for(p2 = root; p2 != NULL; p2 = p2->next){
- while(p2 != NULL && p2->p2_used_within_12 != NO)
- p2 = p2->next;
- if (p2 != NULL){
- if (combotab[FORMULA(p->fighter_ID, p2->fighter_ID)] == NO)
- return 0; //still a match left -- don't clear
- }
- else if (p2 == NULL)
- break; //clear
- }
- }
- return 1; //all possible matches have occurred, clear match counts
- }
- int mark_combo(int x, int y) //mark one combo
- {
- if (combotab[FORMULA(x, y)] == YES){ //it's already yes somehow
- perror("Error: Mark Combo function is not working properly\n");
- getchar();
- exit(1);
- }
- combotab[FORMULA(x, y)] = YES;
- return 1;
- }
- 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
- {
- int i, y;
- for(i = y = 1; i <= 12; i++, y++)
- if (combotab[FORMULA(i, y)] == YES){ //it's already yes somehow
- perror("Error: Mark mirror combo function is not working properly\n");
- getchar();
- exit(1);
- }
- else
- combotab[FORMULA(i, y)] = YES;
- return 1;
- }
- void parse_match(char *match, char *s, char *t);
- void find_IDs(char *name, char *name2, int *ID, int *ID2);
- void unmark_combos(char *matches[], int fighter_count, int match_count) //unmarks 12 matches from combotab[]
- {
- int ID, ID2, i;
- char name[20], name2[20];
- for (match_count--; fighter_count > 0; match_count--, fighter_count--){
- parse_match(matches[match_count], name, name2); //stores fighter names from match into names
- find_IDs(name, name2, &ID, &ID2); //gets ID's based on the names
- combotab[FORMULA(ID, ID2)] = NO; //unmarks match
- }
- }
- void parse_match(char *match, char *s, char *t)
- {
- int i, j;
- for (i = 0; match[i] != 'V'; i++)
- s[i] = match[i];
- s[i-1] = '\0';
- i += 3;
- for (j = 0; match[i] != '\0'; i++)
- t[j++] = match[i];
- t[j] = '\0';
- }
- void find_IDs(char *name, char *name2, int *ID, int *ID2)
- {
- FIGHTER *p = root;
- while (p != NULL && strcmp(p->name, name) != 0)
- p = p->next;
- if (p == NULL){
- perror("ERROR");
- exit(1);
- }
- *ID = p->fighter_ID;
- for (p = root; p != NULL && strcmp(p->name, name2) != 0; p = p->next)
- ;
- if (p == NULL){
- perror("ERROR in FIND_IDS: Fighter pointer is NULL\n");
- exit(1);
- }
- *ID2 = p->fighter_ID;
- }
- int unmark_all_combos(void)
- {
- int i;
- for (i = 0; i < 144; i++)
- combotab[i] = NO;
- }
- void error_code(void){
- perror("ERROR: Not enough space to create name\n");
- getch();
- exit(1);
- }
- void create_all_fighters(void){
- create_fighter("Liu Kang", 1, 0, 0);
- create_fighter("Kung Lao", 2, 0, 0);
- create_fighter("Johnny Cage", 3, 0, 0);
- create_fighter("Reptile", 4, 0, 0);
- create_fighter("Sub-Zero", 5, 0, 0);
- create_fighter("Shang Tsung", 6, 0, 0);
- create_fighter("Kitana", 7, 0, 0);
- create_fighter("Jax", 8, 0, 0);
- create_fighter("Mileena", 9, 0, 0);
- create_fighter("Baraka", 10, 0, 0);
- create_fighter("Scorpion", 11, 0, 0);
- create_fighter("Raiden", 12, 0, 0);
- }
- 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
- {
- FIGHTER *np, *npp;
- npp = NULL;
- for (np = root; np != NULL; np = np->next)
- 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
- np = (FIGHTER *)malloc(sizeof *np);
- if (np == NULL)
- error_code();
- np->next = NULL;
- np->name = strdup_(fighter_name);
- np->fighter_ID = ID;
- np->used_within_12 = used_within_12;
- np->p2_used_within_12 = used_within_12;
- if (root != NULL)
- 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)
- if (root == NULL){ // if root doesn't point to first fighter, point to it
- root = np; //no storage allocation needed, pointing to storage already allocated and with stored data
- }
- }
- char *strdup_(char *s) //function defined in K&R
- {
- char *p;
- 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
- if (p != NULL)
- strcpy(p, s);
- else
- error_code();
- return p;
- }
- /*
- static int i = 1;
- int j, count, dupl = 0;
- char one_match[20];
- for (i = 0; i < 144; i++){
- strcpy(one_match, match[i]);
- count = 0;
- for (j = 0; j < 144; j++){
- if (strcmp(match[j], one_match) == 0)
- count++;
- if (count == 2){
- printf("Error, duplicate match found! :(\n");
- count = 0;
- }
- }
- }
- printf("No duplicates found\n", dupl);
- getch();
- return 0;
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement