c语言大作业,匹配系统,开了三个线程,c89,需要支持pthread.h库。

文件1 color.h

#include <windows.h>
const WORD FORE_BLUE   = FOREGROUND_BLUE;           //蓝色文本属性
const WORD FORE_GREEN  = FOREGROUND_GREEN;          //绿色文本属性
const WORD FORE_RED    = FOREGROUND_RED;            //红色文本属性
const WORD FORE_YELLOW = 6; //(FORE_RED | FORE_GREEN);     //黄色文本属性   //c89标准不允许 (FORE_RED | FORE_GREEN)操作,所以直接给出值了,但是可移植性降低了。
const WORD FORE_GRAY   = FOREGROUND_INTENSITY;      //灰色文本属性                  //如果是c99标准请去掉数字换成后面的表达式
const WORD BACK_BLUE   = BACKGROUND_BLUE;           //蓝色背景属性
const WORD BACK_GREEN  = BACKGROUND_GREEN;          //绿色背景属性
const WORD BACK_RED    = BACKGROUND_RED;            //绿色背景属性
const WORD BACK_PURPLE = 80; //(BACK_BLUE | BACK_RED);      //紫色背景属性
const WORD BACK_CYAN   = 48;//(BACK_BLUE | BACK_GREEN);    //青色背景属性
const WORD BACK_YELLOW = 96;//(BACK_RED | BACK_GREEN);     //黄色背景属性
const WORD BACK_GRAY   = BACKGROUND_INTENSITY;      //灰色背景属性
// 以下为windows改变窗口颜色调用 #define get_yellow SetConsoleTextAttribute(handle_out, FORE_YELLOW) //黄色
#define get_red SetConsoleTextAttribute(handle_out, FOREGROUND_INTENSITY | FORE_RED)//红色
#define get_white SetConsoleTextAttribute(handle_out, FORE_GREEN | FORE_BLUE | FORE_RED) //将三原色混合不就是白色(原色嘛)哈哈哈。
#define get_blue SetConsoleTextAttribute(handle_out, FORE_BLUE) //蓝色
#define get_green SetConsoleTextAttribute(handle_out, FORE_GREEN) //绿色
//暂时只用的上这么多颜色啦void getcolor()
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息
}

文件2 match_data.h

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct people
{int id;//用户id char name[500];//用户名 int grade; //分数 int wait_time; //匹配等待时间
};
struct gaming
{struct people a;struct people b;int average_score;int time_ing;
};

文件3 match_list.h


///存链表操作头文件
#include "sstring.h"
//#include "solve_error.h"
#include"menu.h"
extern int list_size;
typedef struct data_list //链表的结构,包含了match_data.h中的本程序基本数据(id名字和分数),以及一个指向下一个的指针。
{struct people data;struct data_list *next;} list_data;
struct data_list * list_inint(int n) //初始化一个链表(list_data类型),其中包含n个表,不过本程序不需要初始的n个表,只需要初始化。
{list_data * head;list_data * tail;list_data * p;head = tail = p = NULL;list_size=n;while (n--){p = (list_data *) malloc(sizeof(list_data));//给表分配空间 scanf("%d%s%d", &p->data.id, p->data.name, &p->data.grade);p->next = NULL;if (head == NULL){head = p;tail = p;}else{tail->next = p;tail = p;}}return head;//返回头指针
}
list_data * list_add(list_data *head,struct people a,int * kase)//向链表中插入一个数据(插入保证链表按照 “i d” 排好序)。
{list_size++;list_data * p = (list_data *) malloc(sizeof(list_data));//给表分配空间 p->data=a;p->next=NULL;list_data * head1 = head; //创建新表头——用来遍历到刚好比id小的地方,然后放入此次数据。 if(head==NULL||head->data.id>a.id){p->next=head;head=p;return head;}else{while(head1->next!=NULL && head1->next->data.id <= a.id){head1=head1->next;}if(head1->data.id == a.id)//如果出现重id则出现错误输入。{free(p);//出错记得释放空间,防止出现漏洞。error(1);//输出错误信息。list_size--;*kase=1;}else//插入 {p->next = head1->next;head1->next = p;}}return head;//返回新的头指针。
}
list_data * list_remove(list_data *head,struct people a,int *kase)
{list_size--;if(head == NULL){error(2);list_size++;*kase = 1;return head;}if(head->data.id == a.id){list_data * temp = head; head=head->next;free(temp);}else{list_data * head1 = head;while((head1->next != NULL) && (head1->next->data.id !=a.id) )//遍历到要删除的人 {head1=head1->next;}if(head1->next == NULL)//错误2,删除人物不存在。 {error(2);list_size++;*kase = 1;}else{list_data * temp = head1->next;head1->next=head1->next->next; //删除操作free(temp);//记得释放内存。 } }return head;
}
int remove_now(list_data * a)//删除当前节点
{if(a == NULL)return 0;if(a->next==NULL){list_data * temp =a;a=NULL;free(temp);list_size--;return 1;}a->data=a->next->data;list_data * temp =a->next;a->next=a->next->next;free(temp);list_size--;return 1;}
int list_print(list_data * head)
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息list_data *p =head;if(p == NULL){get_red;printf("there if no one in the match pool\n");get_white;}else{int i=1;get_yellow;while(p!=NULL){printf("%3d:id=%2d,name=%s,grade=%5d  waiting for %d seconds\n",i,p->data.id,p->data.name,p->data.grade,p->data.wait_time);p = p->next;i++;}get_white;}return 1;
}

文件4 menu.h

#include<stdio.h>
//#include"color.h"
#include"solve_error.h"
int menu()//主菜单函数
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息 printf("制作者:");get_yellow;printf("罗春阳\n\n");Sleep(1*20);get_white;                                              //这些东西都是调字体颜色的,可以忽略 printf("主菜单\n");Sleep(1*20);get_green;printf("                     注:可以输入'q'(加回车)来刷新页面,(命令不分大小写,可随意大小写)\n"); get_white;printf("########################################################################################################\n");Sleep(1*20);printf("##");get_red;printf("             功能1:加入或删除用户进入匹配池。                  功能2:查看匹配池或游戏池情况       ");Sleep(1*20);get_white;printf("##\n"); printf("##               add/remove ‘id’ ‘username’ ‘grade’       fgamewait fgameing(-t)(-av) fpoolsize ##\n");Sleep(1*20);printf("##");get_red;printf("             功能3:结束某个用户的游戏。                        功能4:查看各种历史                 ");Sleep(1*20);get_white;printf("##\n");  printf("##               gameover ‘id’ or gameover ‘username’             system-history  history         ##\n");Sleep(1*20);printf("##");get_red;printf("             功能5:切换系统信息输出模式。                      功能6:查看帮助                     ");Sleep(1*20);get_white;printf("##\n");printf("##               system-change                                        help                            ##\n");Sleep(1*20); printf("##                                              输入\"exit\"退出程序                                    ##\n");Sleep(1*20);printf("########################################################################################################\n\n");Sleep(1*20);printf("输入代码后回车即可执行相应请求\n"); Sleep(1*20);return 1; }int match_exit()
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息 printf("             ■          ■     \n");Sleep(1*50);printf("   ■      ■■■■      ■     \n");Sleep(1*50);printf("     ■    ■    ■      ■     \n");Sleep(1*50);printf("     ■    ■■■■      ■     \n");Sleep(1*50);printf("           ■    ■■■■■■   \n");Sleep(1*50);printf(" ■■■    ■■■■      ■     \n");Sleep(1*50);printf("     ■    ■    ■      ■     \n");Sleep(1*50);printf("     ■    ■    ■■    ■     \n");Sleep(1*50);printf("     ■  ■■■■■  ■  ■     \n");Sleep(1*50);printf("     ■        ■■  ■  ■     \n");Sleep(1*50);printf("     ■■    ■  ■      ■     \n");Sleep(1*50);printf("     ■    ■    ■      ■     \n");Sleep(1*50);printf("         ■      ■      ■     \n");Sleep(1*50);printf("       ■    ■  ■  ■  ■     \n");Sleep(1*50);printf("               ■      ■       \n");Sleep(1*50);printf("                                \n\n");printf("             ■          ■     \n");Sleep(1*50);printf("   ■      ■■■■      ■     \n");Sleep(1*50);printf("     ■    ■    ■      ■     \n");Sleep(1*50);printf("     ■    ■■■■      ■     \n");Sleep(1*50);printf("           ■    ■■■■■■   \n");Sleep(1*50);printf(" ■■■    ■■■■      ■     \n");Sleep(1*50);printf("     ■    ■    ■      ■     \n");Sleep(1*50);printf("     ■    ■    ■■    ■     \n");Sleep(1*50);printf("     ■  ■■■■■  ■  ■     \n");Sleep(1*50);printf("     ■        ■■  ■  ■     \n");Sleep(1*50);printf("     ■■    ■  ■      ■     \n");Sleep(1*50);printf("     ■    ■    ■      ■     \n");Sleep(1*50);printf("         ■      ■      ■     \n");Sleep(1*50);printf("       ■    ■  ■  ■  ■     \n");Sleep(1*50);printf("               ■      ■       \n");Sleep(1*50);printf("                                \n\n");Sleep(1*50);///printf("        ■        ■            \n");Sleep(1*50);printf("        ■        ■            \n");Sleep(1*50);printf("      ■  ■■■■■■■■■■  \n");Sleep(1*50);printf("    ■            ■            \n");Sleep(1*50);printf("    ■■          ■            \n");Sleep(1*50);printf("  ■  ■  ■■■■■■■■■    \n");Sleep(1*50);printf("      ■  ■      ■      ■    \n");Sleep(1*50);printf("      ■  ■      ■      ■    \n");Sleep(1*50);printf("      ■  ■■■■■■■■■    \n");Sleep(1*50);printf("      ■    ■    ■            \n");Sleep(1*50);printf("      ■      ■■              \n");Sleep(1*50);printf("      ■        ■■            \n");Sleep(1*50);printf("      ■      ■    ■■        \n");Sleep(1*50);printf("      ■  ■■          ■■■  \n");Sleep(1*50);printf("      ■■                ■    \n");Sleep(1*50);printf("                                \n\n");printf("                                \n");Sleep(1*50);printf("      ■■■■■■■■■■■    \n");Sleep(1*50);printf("      ■        ■        ■    \n");Sleep(1*50);printf("      ■        ■        ■    \n");Sleep(1*50);printf("      ■        ■        ■    \n");Sleep(1*50);printf("      ■■■■■■■■■■■    \n");Sleep(1*50);printf("      ■        ■        ■    \n");Sleep(1*50);printf("      ■        ■        ■    \n");Sleep(1*50);printf("      ■        ■        ■    \n");Sleep(1*50);printf("      ■■■■■■■■■■■    \n");Sleep(1*50);printf("      ■        ■        ■    \n");Sleep(1*50);printf("      ■        ■        ■    \n");Sleep(1*50);printf("    ■          ■        ■    \n");Sleep(1*50);printf("    ■          ■    ■  ■    \n");Sleep(1*50);printf("  ■                    ■      \n");Sleep(1*50);printf("                                \n\n\n");get_red;printf("                  虽然程序已经结束,但是您的操作历史和系统历史以及游戏池仍然会存下来\n                  他们存在history.txt,system_history.txt和game.txt中\n");get_white;Sleep(1*1000);system("pause");exit(0);}int help()
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息 FILE * fp;fp = fopen("readme.txt","r");char kmp[2000];while(fscanf(fp,"%[^\n]%*c",kmp)==1){if(!strcmp(kmp,"功能")){get_red;puts(kmp);get_white;}else puts(kmp);}puts("");return 0;
}
int enter()
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息 get_red;printf("按回车进入系统\n");get_white;if(!scanf("%*[^\n]%*c")){getchar();}return 0;
}

文件5 solve_error.h

#include"color.h"
#include<stdio.h> void error(int n)//处理错误的函数
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息if(n==1){get_red;printf("\n error\n 错误代码:001 重id__请勿反复加入匹配!\n");get_white;}else if(n==2){get_red;printf("\n error\n 错误代码:002 此id用户未进行匹配__请勿反复退出或开始游戏!\n");get_white;}else if(n==3){get_red;printf("\n error\n 错误代码:003 输入格式错误__请按照上方格式输入!\n");get_white;}else if(n==4){get_red;printf("\n error\n 错误代码:004 未找到此游戏用户__此用户未开始游戏,无法结束!\n");get_white;}else if(n==5){get_red;printf("\n error\n 错误代码:005 无法加入此用户__此用户已经开始游戏,无法再次匹配!\n");get_white;}return;
}

文件6 sstring.h

//本程序需要用到的字符串处理函数
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"match_data.h"int search_kongge(char a[])//判断空格个数
{int flag = 0;int ans = 0;int i;for (i = 0; a[i] != '\0'; i++){if (a[i] == ' ' && flag > 0)ans++;else{flag++;}}return ans;
}
int fengge_one(char get[],char d[])//分割成一个空格的版本
{sscanf(get,"%s",d);if(!strcmp(d,"gameover")){sscanf(get,"%*s%s",d);return 0;}else{return 1;}
}
int fengge_three(char get[], char d[], struct people *a)//分割成三个空格的版本
{sscanf(get, "%s%d%s%d", d, &a->id, a->name, &a->grade);return 1;
}
int string_sourch(char a[], int n)
{if (n == 1){int i;for (i = 0; a[i] != '\0'; i++) //先转换大小写{if (a[i] >= 'A' && a[i] <= 'Z')a[i] = a[i] - 'A' + 'a';}if (!strcmp(a, "add"))return 1;else if (!strcmp(a, "remove"))return 2;elsereturn 3;}else{int i;for (i = 0; a[i] != '\0'; i++) //先转换大小写{if (a[i] >= 'A' && a[i] <= 'Z')a[i] = a[i] - 'A' + 'a';}if (!strcmp(a, "fgamewait"))return 1;else if (!strcmp(a, "fgameing"))return 2;else if(!strcmp(a,"fpoolsize"))return 4;else if(!strcmp(a,"q"))return 5;else if(!strcmp(a,"exit"))return 0;else if(!strcmp(a,"history"))return 6;else if(!strcmp(a,"system-history"))return 7;else if(!strcmp(a,"system-change"))return 8;else if(!strcmp(a,"help"))return 9;else if(!strcmp(a,"fgameing-t"))return 10;else if(!strcmp(a,"fgameing-av"))return 11;elsereturn 3;}
}

文件7 game_pool.h

#include<stdio.h>
/*struct gaming
{struct people a;struct people b;int average_score;};*/
//#include"color.h"
//#include "menu.h"
//#include"match_data.h"
//#include"sstring.h"
#include"match_list.h"
int gameing_print(struct gaming a[],int size)//默认输出游戏进行时间
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息int i;for(i=0;size>i;i++){printf("%d:\n",i+1);get_red;printf("%s",a[i].a.name);get_white;printf("  vs  ");get_blue;printf("%s\n",a[i].b.name);get_white;printf("played:%d seconds\n\n",a[i].time_ing); }if(size == 0){get_red;printf("\nthere is no one in gameing\n");get_white;}puts("");return 0;
}int gameing_print_a(struct gaming a[],int size)//输出游戏双方的平均分数
{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息int i;for(i=0;size>i;i++){printf("%d:\n",i+1);get_red;printf("%s",a[i].a.name);get_white;printf("  vs  ");get_blue;printf("%s\n",a[i].b.name);get_white;printf("平均分数为:%d 分\n\n",a[i].average_score); }if(size == 0){get_red;printf("\nthere is no one in gameing\n");get_white;}puts("");return 0;
}

主c文件  用户动态匹配系统.c

int list_size=0;//当前链表长度
//#include "match_list.h"
#include <pthread.h>
#include "game_pool.h"//保存
//#include"color.h"
int system_history=0;//全局变量,用来改变系统问题是否输出到屏幕。0表示不输出。 int id_card[10000000];//对id进行判重,防止重复id加入游戏。
//int name_card[1000000]; //本来想写一个字符串哈希来对名字判重的,但是没写了,因为没什么意义,名字可以重复。
pthread_mutex_t id_m;struct mutex_match//定义了一个带锁的链表,方便多线程时的管理。//此为匹配池 匹配池为动态池,动态存储。
{list_data * head ;pthread_mutex_t m;}q;struct mutex_game //这是游戏池。//游戏池将存在文件game.txt中。
{struct gaming pool[2000];int cnt;pthread_mutex_t m;
}gameing;struct gaming ttemp[2000];//用来处理游戏池的删除//做中介作用
//
pthread_mutex_t file_game_m;//文件锁,防止多进程同时对文件进行增删查改。 pthread_mutex_t file_history_m;//操作历史文件——锁。 pthread_mutex_t file_history_system_m;//系统操作历史文件(例如match 1 and 2 succeed)。——锁。int add_to_game(struct people a,struct people b)//加入正在进行中的游戏池。
{pthread_mutex_lock(&gameing.m);gameing.pool[gameing.cnt].a=a;gameing.pool[gameing.cnt].b=b;gameing.pool[gameing.cnt].average_score=((a.grade+b.grade)>>1);gameing.cnt++;pthread_mutex_unlock(&gameing.m);
}
/*#############此 处 为 匹 配 线 程 开 始 #####################*/
int match_server(list_data * head)//匹配程序,遍历匹配,选取合法的用户匹配,每一次匹配提高每个用户的匹配(阈值)(时间越久越容易匹配到人(不过可能被虐菜))。
{int a=0;list_data * i;for(i = head ; i!=NULL ; i = i->next){i->data.wait_time++;}for(i = head ; i!=NULL ; i = i->next)//遍历进行匹配 {list_data * j;for(j = i->next ; j!=NULL ; j = j->next){int t=abs(i->data.grade - j->data.grade);if((t <= (i->data.wait_time * 5))&&(t <= (j->data.wait_time * 5)))//符合要求则进入游戏池,并从匹配池删除 {add_to_game(i->data,j->data);pthread_mutex_lock(&id_m);//更新id id_card[i->data.id]=1;id_card[j->data.id]=1;pthread_mutex_unlock(&id_m);if(system_history)//存历史 {printf("match %d and %d succeed\n",i->data.id,j->data.id);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"match %d and %d succeed\n",i->data.id,j->data.id);fclose(fp);pthread_mutex_unlock(&file_history_system_m);if(j->next==NULL){q.head=list_remove(q.head,j->data,&a);}elseremove_now(j);if(i->next==NULL||i==head){q.head=list_remove(q.head,i->data,&a);}else{remove_now(i);}return 0;}}}return 0;
}void * solve_task(void *argc)//解决匹配问题
{while(1){while (list_size>0)//一秒匹配一次 {pthread_mutex_lock(&q.m);match_server(q.head);pthread_mutex_unlock(&q.m);Sleep(1000);}Sleep(1000);}
}
/*############# 此 处 为 匹 配 线 程 的 结 尾 #####################*///-----------------------------------------------------------------------------------------------------------------------------------------分割线 /*############# 此 处 为 游 戏 线 程 的 开 始 #####################*/
int game_file_add()//每五秒刷新一次 游戏进行时文件
{pthread_mutex_lock(&gameing.m);pthread_mutex_lock(&file_game_m);FILE *fp;fp = fopen("game.txt","w");int i;for(i=0;gameing.cnt>i;i++){gameing.pool[i].time_ing+=5;//每次刷新游戏时间加5 fprintf(fp,"%d:\n",i+1);fprintf(fp,"    %d   %s   %d\n",gameing.pool[i].a.id,gameing.pool[i].a.name,gameing.pool[i].a.grade);fprintf(fp,"         vs                 gameing_time:%ds\n",gameing.pool[i].time_ing);fprintf(fp,"    %d   %s   %d\n\n",gameing.pool[i].b.id,gameing.pool[i].b.name,gameing.pool[i].b.grade);}fclose(fp);pthread_mutex_unlock(&gameing.m);pthread_mutex_unlock(&file_game_m);return 0;
}int game_remove_name(char name[])//结束某个用户的游戏——用名称进行删除。
{pthread_mutex_lock(&gameing.m);int temp_cnt=0; int i;for(i = 0;gameing.cnt>i;i++){if((!strcmp(name,gameing.pool[i].a.name)) || (!strcmp(name,gameing.pool[i].b.name)) ){pthread_mutex_lock(&id_m);id_card[gameing.pool[i].a.id]=0;id_card[gameing.pool[i].b.id]=0;pthread_mutex_unlock(&id_m);continue;}ttemp[temp_cnt++]=gameing.pool[i];}if(temp_cnt == gameing.cnt){pthread_mutex_unlock(&gameing.m);if(system_history)//存历史 {printf("gameover '%s' false\n",name);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"gameover '%s' false\n",name);fclose(fp);pthread_mutex_unlock(&file_history_system_m);return 1;}else{for(i=0;temp_cnt>i;i++)//在前面定义过了 {gameing.pool[i]=ttemp[i];}gameing.cnt=temp_cnt;} pthread_mutex_unlock(&gameing.m);if(system_history)//存历史{printf("gameover '%s' succeed\n",name);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"gameover '%s' succeed\n",name);fclose(fp);pthread_mutex_unlock(&file_history_system_m);//记得开锁。 return 0;
}int game_remove_id(int id)//结束某个用户的游戏——用id进行删除。
{pthread_mutex_lock(&gameing.m);int temp_cnt=0; int i; for(i = 0;gameing.cnt>i;i++){if((id == gameing.pool[i].a.id) || (id == gameing.pool[i].b.id)){pthread_mutex_lock(&id_m);id_card[gameing.pool[i].a.id]=0;id_card[gameing.pool[i].b.id]=0;pthread_mutex_unlock(&id_m);continue;}ttemp[temp_cnt++]=gameing.pool[i];}if(temp_cnt == gameing.cnt){pthread_mutex_unlock(&gameing.m);if(system_history)//存历史 {printf("gameover '%d' false\n",id);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"gameover '%d' false\n",id);fclose(fp);pthread_mutex_unlock(&file_history_system_m);return 1;}else{for(i=0;temp_cnt>i;i++)//前面定义过了 {gameing.pool[i]=ttemp[i];}gameing.cnt=temp_cnt;} pthread_mutex_unlock(&gameing.m);if(system_history)//存历史{printf("gameover '%d' succeed\n",id);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"gameover '%d' succeed\n",id);fclose(fp);pthread_mutex_unlock(&file_history_system_m);//记得开锁。 return 0;
}void *solve_gaming(void *argc)//解决游戏问题
{while(1){while(gameing.cnt>0){game_file_add();Sleep(5000);}Sleep(5000);}
}
/*############# 此 处 为 游 戏 线 程 的 结 尾 #####################*//*############# 此 处 为 历 史 文 件 处 理 的 开 始 #####################*/int print_history()输出history.txt文件。
{pthread_mutex_lock(&file_history_m);FILE * fp;int i=1;fp = fopen("history.txt","r");char kmp[200];while(fscanf(fp,"%[^\n]%*c",kmp)==1){printf("%d:",i);puts(kmp);i++;}puts("");pthread_mutex_unlock(&file_history_m);return 0;
}int print_system_history()///输出系统信息___history_system.txt文件
{pthread_mutex_lock(&file_history_system_m);FILE * fp;int i=1;fp = fopen("history_system.txt","r");char kmp[200];while(fscanf(fp,"%[^\n]%*c",kmp)==1){printf("%d:",i);puts(kmp);i++;}puts("");pthread_mutex_unlock(&file_history_system_m);return 0;
}
/*############# 此 处 为 历 史 文 件 处 理 的 结 尾 #####################*//*############# 此 处 为 解 决 游 戏 池 排 序 输 出 的 问 题 开 始 #####################*/
int cmp_time(const void *p1,const void *p2)//时间排序函数
{const struct gaming *a1 = (const struct gaming *)p1;const struct gaming *a2 = (const struct gaming *)p2;return a1->time_ing > a2->time_ing;}
int cmp_average(const void *p1,const void *p2)//平均分数排序函数
{const struct gaming *a1 = (const struct gaming *)p1;const struct gaming *a2 = (const struct gaming *)p2;return a1->average_score > a2->average_score;}int gameing_print_time(struct gaming a[],int n)//按时间排序后输出函数
{qsort(a,n,sizeof(struct gaming),cmp_time);gameing_print(a,n);return 0;}
int gameing_print_average(struct gaming a[],int n) //按平均成绩排序后输出函数。
{qsort(a,n,sizeof(struct gaming),cmp_average); gameing_print_a(a,n);return 0;
}
/*############# 此 处 为 解 决 游 戏 池 排 序 输 出 的 问 题 结 尾 #####################*/int main(void)//主函数开始处、、、、、、、、
{//先输出教程help();//定义在menu.h enter();//阻断函数。。给用户看说明的时间//定义在menu.hsystem("cls"); //正式进入系统 FILE *file_to_zero;//初始化各个文件防止上一次运行残留。 file_to_zero = fopen("history.txt","w");fclose(file_to_zero);file_to_zero = fopen("history_system.txt","w");fclose(file_to_zero);//初始化 history文件。file_to_zero = fopen("game.txt","w");fclose(file_to_zero);menu(); //输出菜单。char get[700]; //读取整行输入 char doing[200];//存临时操作名称 struct people a;//存临时用户。 gameing.cnt=0;q.head=list_inint(0);//初始化链表pthread_t th1_match;//定义第一个线程 //用于匹配 pthread_t th2_game;//定义第二个线程// 用于进行游戏池更新。pthread_create(&th1_match,NULL,solve_task,NULL);//创建第一个线程 (匹配线程,每一秒匹配一次) pthread_create(&th2_game,NULL,solve_gaming,NULL);//创建第二个线程(游戏线程,处理游戏进行时的条件改变__五秒刷新一次) while(1==1)//反复循环读取用户输入{if(!scanf("%[^\n]%*c",get))//输入操作 {getchar();continue;}pthread_mutex_lock(&file_history_m);   //存操作历史。 FILE *history_file_hand;history_file_hand = fopen("history.txt","a+");fprintf(history_file_hand,"%s\n",get);fclose(history_file_hand);pthread_mutex_unlock(&file_history_m);/int kongge=search_kongge(get);//输入按空格分为0,1,3空格形式命令 if(kongge != 3 && kongge != 0 && kongge !=1)//都不是则error error(3);else if(kongge == 3)//三空格命令 {fengge_three(get,doing,&a);//三空格的字符串 分割出来。 int temp=0;temp=string_sourch(doing,1);//以一号方式执行函数  //为添加和删除匹配(方式 ) if(temp==3)error(3);else if(temp == 1)//添加用户 {int p=0;pthread_mutex_lock(&q.m);//把链表上锁,防止同时修改。 pthread_mutex_lock(&id_m);//id也要上锁。 if(id_card[a.id]){p=1;error(5);}elseq.head = list_add(q.head,a,&p);pthread_mutex_unlock(&q.m);//释放 pthread_mutex_unlock(&id_m);if(!p)  //处理系统信息,判断添加成功与否 {pthread_mutex_lock(&id_m);//更新id id_card[a.id]=1;pthread_mutex_unlock(&id_m);if(system_history){printf("add %d succeed\n",a.id);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"add %d succeed\n",a.id);fclose(fp);pthread_mutex_unlock(&file_history_system_m);}else{if(system_history){printf("add %d false\n",a.id);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"add %d false\n",a.id);fclose(fp);pthread_mutex_unlock(&file_history_system_m);}///}else if(temp == 2)//同上,删除用户 {int p=0;pthread_mutex_lock(&q.m);//把链表上锁,防止同时修改。 q.head = list_remove(q.head,a,&p);pthread_mutex_unlock(&q.m);if(!p)//处理系统信息,判断删除成功与否  {if(system_history){printf("remove %d succeed\n",a.id);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"remove %d succeed\n",a.id);fclose(fp);pthread_mutex_unlock(&file_history_system_m);}else{if(system_history){printf("remove %d false\n",a.id);}pthread_mutex_lock(&file_history_system_m);FILE *fp;fp =fopen("history_system.txt","a+");fprintf(fp,"remove %d false\n",a.id);fclose(fp);pthread_mutex_unlock(&file_history_system_m);}/// }}else if(kongge == 1)//一空格命令 {if(fengge_one(get,doing))//先分割 {error(3);continue;}if(doing[0]>='0'&&doing[0]<='9')//判断数字id还是名字 {int id=0;int i;for(i=0;doing[i]!='\0';i++){id=id*10 +(doing[i]-'0');}if(game_remove_id(id)){error(4);}}else if(game_remove_name(doing)){error(4);}}else if(kongge == 0)//零空格命令 {int temp=string_sourch(get,2);//以二号方式执行。//是某些单条命令 if(temp ==0)//exit {pthread_mutex_lock(&file_game_m);pthread_mutex_lock(&file_history_m);pthread_mutex_lock(&file_history_system_m);match_exit();pthread_mutex_unlock(&file_game_m);pthread_mutex_unlock(&file_history_m);pthread_mutex_unlock(&file_history_system_m);}else if(temp==3)//没这个命令 error(3);else if(temp == 1)//fgamewait {pthread_mutex_lock(&q.m);//把链表上锁,防止同时修改。 list_print(q.head);pthread_mutex_unlock(&q.m);//释放 }else if(temp == 2)//fgameing{pthread_mutex_lock(&gameing.m);gameing_print(gameing.pool,gameing.cnt);pthread_mutex_unlock(&gameing.m);}else if(temp == 4)//fpoolsize{HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄  CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体  GetConsoleScreenBufferInfo(handle_out, &csbi);      //获得窗口缓冲区信息           printf("now the pool size is: ");get_red;printf("%d\n",list_size);get_white;}else if(temp == 5)//q//刷新 {system("cls");menu();}else if(temp == 6)//history {print_history();}else if(temp == 7)//system-history {print_system_history();}else if(temp == 8)//system-change{system_history ^=1;if(system_history == 1)printf("change to system_out (此模式下将及时的输出所有系统信息)\n");else{printf("change to system_in(关闭系统信息输出)\n");}}else if(temp == 9)//help{help();//直接输出帮助____定义在menu.h中。 }else if(temp == 10)//fgameing-t//按时间排序从小到大输出。{pthread_mutex_lock(&gameing.m);gameing_print_time(gameing.pool,gameing.cnt);pthread_mutex_unlock(&gameing.m);}else if(temp == 11)//fgameing-av//按比赛双方的平均分数排序从小到大输出。{pthread_mutex_lock(&gameing.m);gameing_print_average(gameing.pool,gameing.cnt);pthread_mutex_unlock(&gameing.m);}}}return 0;//                            _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                            O\ = /O
//                        ____/`---'\____
//                      .   ' \\| |// `.
//                       / \\||| : |||// \
//                     / _||||| -:- |||||- \
//                       | | \\\ - /// | |
//                     | \_| ''\---/'' | |
//                      \ .-\__ `-` ___/-. /
//                   ___`. .' /--.--\ `. . __
//                ."" '< `.___\_<|>_/___.' >'"".
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |
//                 \ \ `-. \_ __\ /__ _/ .-` / /
//         ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//
//         .............................................
//                  佛祖保佑             永无BUG
//          佛曰:
//                  写字楼里写字间,写字间里程序员;
//                  程序人员写程序,又拿程序换酒钱。
//                  酒醒只在网上坐,酒醉还来网下眠;
//                  酒醉酒醒日复日,网上网下年复年。
//                  但愿老死电脑间,不愿鞠躬老板前;
//                  奔驰宝马贵者趣,公交自行程序员。
//                  别人笑我忒疯癫,我笑自己命太贱;
//                  不见满街漂亮妹,哪个归得程序员?}

教程文件 readme.txt (必须与主函数文件处于同一文件夹下运行)

功能1:add      remove添加用户和删除用户进匹配池(匹配系统会根据添加进来的用户动态的进行匹配,每一个用户第一秒只会匹配根自己分数相差5分以内的对手,但是每过一秒他们的阈值会增加5分(就算是与跟自己分差很多的对手游戏也比没人好)及第二秒就可能会匹配到跟自己相差10分的对手了,以此类推)。add操作。add+(id)+(user_name)+(user_grade)             中间用空格隔开回车即可添加,(id和名字和分数)(其实是模拟前端用户点击匹配然后进行的操作--这里没有图形界面所以用linux类型的命令进行交互)remove操作。remove+(id)+(user_name)+(user_grade)             中间用空格隔开回车即可删除,(id和名字和分数)(模拟前端用户点击取消匹配然后进行的操作,注意,用户可能会匹配成功,如果匹配成功了就无法取消了。)
功能2:fgamewait     fgameing(-t)(-av)          fpoolsize查看匹配池或游戏池情况(匹配系统随时可能会匹配成功,成功的人会移除匹配池,所以我们随时可以查看一下匹配池情况(可看到池中各种数值))fgamewait(输入此命令然后回车,可以看到还在等待匹配的用户即匹配池中的所有人的详细情况)例如输出1:id= 1,name=lcy,grade= 1500 waiting for 5 secondsfgameing(-t)(-av)(输入此命令然后回车,可以看到正在游戏的用户即游戏池中人的数量,包括他们的游戏时长,并且这些信息存在game.txt中结束程序也不会消失)(可以加上后缀(-t)或者(-av)(分别表示按游戏"进行时间"和游戏玩家的"平均分数"从小到大排序后输出)(例如:(fgameing-t) (fgameing-av))例如输出1:lcy  vs  hdmplayed:5 secondsfpoolsize(输入此命令然后回车,可以看到还在等待匹配的用户即匹配池中人的数量)例如输出now the pool size is: 0
功能3:gameover 'id'          gameover 'name'结束某个用户的游戏(用来模拟游戏结束前端向服务器发送的请求)(用户必须要正在游戏才能结束哦)gameover+(id)或者gameover+(user_name) (中间用空格隔开回车即可删除)(id 和 名字 都行效果一样)随后那个用户就会从游戏池中被删除。。当然game.txt中他也会被删除。
功能4:查看各种历史history  (输入此命令然后回车,可以看到自己的所有历史输入,他将按顺序展示出来,(包括无意义的命令)(这些信息存在history.txt文件中))例如输出1:add 1 罗春阳 15002:add 2 hdm 15303:fgame4:fgamewaitsystem-history(输入此命令然后回车,可以看到系统的所有历史信息,他将按顺序展示出来,(系统每次匹配到一个人或者加入一个用户都会产生一个信息)(这个信息存在history_system.txt文件中))例如输出1:add 1 and 2 succeed功能5:切换系统信息输出模式system-change(输入此命令然后回车,可以将系统输出及时的输出到终端屏幕上)(系统每次匹配到一个人或者加入一个用户都会产生一个信息)(开启输出后这个信息将能及时的展示在终端屏幕上)(再输入一次即可关闭)。
功能6:查看帮助help(输入此命令然后回车 将再次展示此页面)输入一个字母'q'加回车可以刷新页面(如果你觉得页面太长不舒服的话)。

以上

C语言大作业——匹配系统相关推荐

  1. C语言大作业车辆租赁系统,汽车租赁管理系统———c语言课程设计.doc

    word文档 可自由复制编辑 #include #include #include #include struct member { int cardnum; char lendcar[10]; }m ...

  2. c语言作业查询,C语言大作业学生成绩查询系统源代码.doc

    C语言大作业学生成绩查询系统源代码 #include #include struct student { char name[20]; char speciality[10]; int C; int ...

  3. 蔬菜信息配送系统c语言编程,c语言大作业物流配送系统程序(10页)-原创力文档...

    c语言大作业物流配送系统程序 #include #include #include //日期 struct date { int year; int month; int day; }; //订单链表 ...

  4. 1008c语言答案,c语言大作业题目01008.doc

    c语言大作业题目01008 一.学生信息管理程序 基本要求: 1.要求实现学生信息的查找.添加.删除.修改.浏览.保存.从文件读取.查看奖学金信息8个功能,每个功能模块均能实现随时从模块中退出,而且可 ...

  5. 学委作业管理系统c语言,c语言大作业-学生信息管理系统.doc

    c语言大作业-学生信息管理系统.doc 课程设计报告书 题目:学生信息管理系统设计 学 院 电子与信息学院 专 业 电子信息类 学生姓名 学生学号 指导教师 课程编号 135160 课程学分 1学分 ...

  6. C语言大作业:旅游资讯管理系统

    C语言大作业:旅游资讯管理系统 题目: 一.主体功能点要求: 1.设计主菜单实现用户交互 a.添加旅游资讯记录 每条记录至少包含如下项:编号.日程安排.费用.点赞数.添加旅游资讯记录时,要求键盘输入对 ...

  7. c语言大作业开题报告,c语言开题报告

    本栏目为关于c语言开题报告和开题报告的论文范文,免费给你写作c语言大作业开题报告提供相关文献资料. 摘要:在一套试卷中,重复题问题是影响考试质量的一个重要因素.该文针對C语言试卷中选择题间易出现重复题 ...

  8. c语言大作业参考书,C语言大作业设计-

    <C语言大作业设计->由会员分享,可在线阅读,更多相关<C语言大作业设计-(17页珍藏版)>请在人人文库网上搜索. 1.常州工学院c语言作业设计规格标题:通信记录管理系统二级学 ...

  9. 大一c语言大作业课题大全,昆明理工大学大一C语言大作业题目.doc

    昆明理工大学大一C语言大作业题目 综合性实践排序求平均值(包括将数拆散求最大最小值).函数ReadDat()随机产生100个存放到数组aa中00个jsSort()函数的功能是:进行降序排列.最后调用函 ...

最新文章

  1. java父类调用被子类重写的方法
  2. KISSY 库 demo
  3. 十、探索性数据分析的图形化探索
  4. 高性能JavaScript 读书笔记
  5. python面向对象类_python:面向对象(类)
  6. FreeMaker+Xml导出word(含图片)
  7. 在置信区间下置信值的计算_使用自举计算置信区间
  8. linux中自动挂载脚本,LIUNX一键自动挂载脚本,宝塔磁盘LIUNX一键分区磁盘 | 帮助信息-动天数据...
  9. 洛谷团队月赛题:题解
  10. C#中as和is关键字
  11. BLOB数据类型、事务
  12. 项目实战之服务端分页的实现——SQL
  13. android 7.0 截图,Android,_7.0系统拍照后,使用系统截图功能,截图保存时崩溃如何解决,Android - phpStudy...
  14. rbf java_RBF网络
  15. windows关闭被占用的端口
  16. Vivado下载 安装 与 和谐教程
  17. 基于DSP/FPGA的超高速跳频系统基带设计与实现
  18. Android studio MacBook快捷键
  19. Android SDK版本以及对应的平台版本、版本名称
  20. python3识别简单验证码

热门文章

  1. 银行家算法(操作系统)
  2. 入行3D游戏建模,了解行业所需,让你少走弯路
  3. nfc支持饭卡吗_都2020年了,听说你还在丢饭卡??
  4. 如何保证数据库和缓存双写一致性?
  5. auto.exe F0D78D11.DLL F77B20D5.EXE专杀
  6. 10 款超级实用的Chrome 黑科技插件
  7. 油烟排放浓度监控系统在浙江省环保治理的应用
  8. Contest_6 0619 By lhq
  9. 3DSMAX渲染被铁链束缚的花朵-3D建模教程
  10. 计算机的桌面窗户是什么,怎么设置电脑桌面便签小窗口,电脑桌面归纳事情的小窗口...