标签:style blog http color io os ar for 2014
server.cpp
#include <cstring> #include <cstdlib> #include <stdio.h> #include <unistd.h> #include <iostream> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <pthread.h> #include <ctime> #include <cctype> #include "usermysql.h" #include "poke.h" using namespace std; #define MYPORT 8887 #define MYPORT2 8888 #define MYPORT3 8889 #define QUEUE 20 #define BUFFER_SIZE 150 #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); } while (0) typedef map< string,vector<poke> > PLAYERLIST; int server_sockfd; struct sockaddr_in server_sockaddr; int ready_num; queue<string> UserSequence; PLAYERLIST player; string first, landlord; string landlordcards[3]; int times; bool yes=0; const int gameID = 1001; /* RegisterUser return 3 kinds of values 1: success 2: username duplicated -1: error */ int RegisterUser(int conn){ char username[50], pwd[20]; recv(conn, username, sizeof(username), 0); int sta = UsernameExist(username); if(sta==1){ send(conn, "usernameexist", sizeof("usernameexist"), 0); return 2; } else if(sta==0){ send(conn, "usernamenoexist", sizeof("usernamenoexist"), 0); recv(conn, pwd, sizeof(pwd), 0); if(UserInsert(username, pwd)==1){ send(conn, "successregister", sizeof("successregister"), 0); return 1; } else{ send(conn, "failregister", sizeof("failregister"), 0); return -1; } } else{ return -1; } } int login(int conn){ char username[50], password[20]; recv(conn, username, sizeof(username), 0); if(strcmp(username, "--exit")==0) return 0; int sta0 = UsernameExist(username); if(sta0==1){ int sta = UserOnline(username); if(sta==0){ send(conn, "inputpassword", sizeof("inputpassword"), 0); recv(conn, password, sizeof(password), 0); int sta2=PasswordCorrect(username, password); if(sta2==1){ int sta3=StatusTurnOn(username); if(sta3==1){ send(conn, "successlogin", sizeof("successlogin"), 0); return 1; } else{ send(conn, "faillogin", sizeof("faillogin"), 0); return -1; } } else if(sta==0){ send(conn, "passwordincorrect", sizeof("passwordincorrect"), 0); return 2; } else{ send(conn, "fail", sizeof("fail"), 0); return -1; } } else if(sta==1){ send(conn, "usernameonline", sizeof("usernameonline"), 0); return 2; } else{ send(conn, "fail", sizeof("fail"), 0); return -1; } } else if(sta0==0){ send(conn, "usernameexist", sizeof("usernameexist"), 0); return 2; } else{ send(conn, "fail", sizeof("fail"), 0); return -1; } } void BeforeEnter(int conn){ char buffer[BUFFER_SIZE]; //客户端发回去的信息不带回车 //一开始询问用户要注册登录,已有账户登录,匿名登录还是退出 int flag=-1; while(1){ recv(conn, buffer, sizeof(buffer), 0); if(strcmp(buffer,"1\n")==0){ flag=-1; send(conn, "register", sizeof("register"), 0); while(1){ flag = RegisterUser(conn); if(flag==2) continue; else break; } if(flag==0) continue; else if(flag==-1) exit(1); else break; } else if(strcmp(buffer,"2\n")==0){ send(conn, "login", sizeof("login"), 0); int flag=-1; while(1){ flag=login(conn); if(flag==2) continue; else break; } if(flag==0) continue; else if(flag==1) break; else exit(1); } else{ send(conn, "quit", sizeof("quit"), 0); break; } } } void DuringReady(int conn){ char buffer[BUFFER_SIZE]; while(1){ recv(conn, buffer, sizeof(buffer), 0); while(!isalnum(buffer[0])) recv(conn, buffer, sizeof(buffer), 0); if(strcmp(buffer, "clientready") == 0){ send(conn, "yourusername", sizeof("yourusername"), 0); recv(conn, buffer, sizeof(buffer), 0); if(StatusTurnReady(buffer)==1){ send(conn, "successready", sizeof("successready"), 0); break; } else{ send(conn, "fail", sizeof("fail"), 0); ERR_EXIT("status turn ready error"); } } else if(strcmp(buffer, "userlogout")==0){ send(conn, "yourusername", sizeof("yourusername"), 0); recv(conn, buffer, sizeof(buffer), 0); if(StatusTurnOff(buffer)==1){ send(conn, "successlogout", sizeof("successlogout"), 0); continue; } else{ send(conn, "fail", sizeof("fail"), 0); ERR_EXIT("status turn off error"); } } else ERR_EXIT("command error"); } } void *BigProcess(void *arg){ int conn; ///客户端套接字 struct sockaddr_in client_addr; socklen_t length = sizeof(client_addr); ///成功返回非负描述字,出错返回-1 conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length); if(conn<0) ERR_EXIT("connect error"); BeforeEnter(conn); DuringReady(conn); ready_num++; while(ready_num!=3){ sleep(2); } send(conn, "allready", sizeof("allready"), 0); close(conn); pthread_exit(NULL); return NULL; } void *CallLandlord(void *arg){ int conn; ///客户端套接字 struct sockaddr_in client_addr; socklen_t length = sizeof(client_addr); ///成功返回非负描述字,出错返回-1 conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length); if(conn<0) ERR_EXIT("connect error"); char buffer[BUFFER_SIZE]; send(conn, "yourusername", sizeof("yourusername"), 0); recv(conn, buffer, sizeof(buffer), 0); string usernow = buffer; while(UserSequence.front() != usernow) sleep(3); times=1; send(conn, "calllandlord", sizeof("calllandlord"), 0); recv(conn, buffer, sizeof(buffer), 0); if(strcmp(buffer, "y")==0){ times*=2; if(usernow == first){ yes=1; landlord = first; } else if(!yes) landlord = usernow; } else if(strcmp(buffer, "n")==0);//do nothing else ERR_EXIT("calllandlord error"); UserSequence.pop(); ready_num++; while(ready_num!=3) sleep(2); strcpy(buffer, landlord.c_str()); //send landlord name to user send(conn, buffer, sizeof(buffer), 0); close(conn); pthread_exit(NULL); return NULL; } void SocketConn(int port){ server_sockfd = socket(AF_INET,SOCK_STREAM, 0); server_sockaddr.sin_family = AF_INET; server_sockaddr.sin_port = htons(port); server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); int on = 1; if (setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) ERR_EXIT("setsockopt error"); if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1) ERR_EXIT("bind error"); if(listen(server_sockfd,QUEUE) == -1) ERR_EXIT("listen error"); } void *InGame(void *arg){ int conn; ///客户端套接字 struct sockaddr_in client_addr; socklen_t length = sizeof(client_addr); ///成功返回非负描述字,出错返回-1 conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length); if(conn<0) ERR_EXIT("connect error"); char buffer[BUFFER_SIZE]; send(conn, "yourusername", sizeof("yourusername"), 0); recv(conn, buffer, sizeof(buffer), 0); char cards[BUFFER_SIZE]; string usernow = buffer; strcpy(cards ,CardsToString(player[usernow]).c_str()); send(conn, cards, sizeof(cards), 0); while(UserSequence.front() != buffer) sleep(3); close(conn); pthread_exit(NULL); return NULL; } int main(){ // SocketConn(MYPORT); int rc; // ready_num=0; // pthread_t thread[3]; // for(int i=0; i<3; i++){ // rc = pthread_create(&thread[i], NULL, BigProcess, NULL); // if(rc) ERR_EXIT("pthread create error"); // } // for(int i=0; i<3; i++) pthread_join(thread[i], NULL); // /*-------------------jiao di zhu--------------------------------------*/ // SocketConn(MYPORT2); // while(UserSequence.size()) UserSequence.pop(); // InitUsers(gameID, UserSequence); // ready_num=0; // first = UserSequence.front(); // pthread_t thread2[3]; // for(int i=0; i<3; i++){ // rc = pthread_create(&thread2[i], NULL, CallLandlord, NULL); // if(rc) ERR_EXIT("pthread create error"); // } // for(int i=0; i<3; i++) pthread_join(thread2[i], NULL); // SetLandlord(gameID, landlord.c_str()); // /*------------------dou di zhu-------------------------------------------------*/ SocketConn(MYPORT3); InitCards(); ShuffleCards(); setLandlordCards(landlordcards); landlord="wutao"; while(UserSequence.size()) UserSequence.pop(); UserSequence.push(landlord);//landlord must be the first InitPlayer(gameID, UserSequence); player.clear(); dealCards(player, UserSequence); pthread_t thread3[3]; for(int i=0; i<3; i++){ rc = pthread_create(&thread3[i], NULL, InGame, NULL); if(rc) ERR_EXIT("pthread create error"); } close(server_sockfd); return 0; }
client.cpp
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <cctype> #include <sys/shm.h> #include <iostream> using namespace std; #define MYPORT 8887 #define MYPORT2 8888 #define BUFFER_SIZE 150 #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); } while (0) int sock_cli; struct sockaddr_in servaddr; char username[BUFFER_SIZE]; char landlord[BUFFER_SIZE]; void BeginPrompt(){ puts("您的选择是:"); puts("1.我没注册"); puts("2.我想登录"); puts("3.我要匿名登录"); puts("4.我要退出"); } /* when BWR: return 0, it means BWR will be restart return -1 means BWR broke down with error return 1 indicates that everything is ok */ int BeginWithRegis(int sock_cli){ char sendbuf[50], recvbuf[50], sendbuf2[50]; puts("报上名来:"); fscanf(stdin,"%s",sendbuf); while(strlen(sendbuf)==0){ puts("输入不能为空"); fscanf(stdin,"%s",sendbuf); } puts(sendbuf); send(sock_cli, sendbuf, sizeof(sendbuf), 0); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf,"usernameexist")==0){ puts("帐号已被注册"); return 2; } else if(strcmp(recvbuf,"usernamenoexist")==0){ puts("恭喜你,帐号未被注册"); while(1){ puts("请输入密码:"); fscanf(stdin,"%s",sendbuf); while(strlen(sendbuf)==0){ puts("输入不能为空"); fscanf(stdin,"%s",sendbuf); } puts("请再次输入密码"); fscanf(stdin,"%s",sendbuf2); while(strlen(sendbuf2)==0){ puts("输入不能为空"); fscanf(stdin,"%s",sendbuf2); } if(strcmp(sendbuf2, sendbuf)==0){ send(sock_cli, sendbuf, sizeof(sendbuf), 0); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf, "successregister")==0) return 1; else return -1; } else{ puts("两次密码不同,请重新输入"); } } } else{ puts("Fuck! System Error!!!"); return -1; } } int BeginWithLogin(int sock_cli){ char sendbuf[50], recvbuf[50]; puts("请输入用户名"); fscanf(stdin,"%s",sendbuf); while(strlen(sendbuf)==0){ puts("输入不能为空"); fscanf(stdin,"%s",sendbuf); } strcpy(username, sendbuf); send(sock_cli, sendbuf, sizeof(sendbuf), 0); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf,"inputpassword")==0){ puts("请输入密码"); fscanf(stdin,"%s",sendbuf); while(strlen(sendbuf)==0){ puts("输入不能为空"); fscanf(stdin,"%s",sendbuf); } send(sock_cli, sendbuf, sizeof(sendbuf), 0); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf,"successlogin")==0){ puts("可以进去了"); return 1; } else if(strcmp(recvbuf, "passwordincorrect")==0){ puts("密码错误!"); return 2; } else{ puts("login error"); return -1; } } else if(strcmp(recvbuf,"usernameonline")==0){ puts("该用户已经登录"); return 2; } else if(strcmp(recvbuf,"usernameexist")==0){ puts("用户名不存在"); return 2; } else{ return -1; } } void UserBegin(int sock_cli){ char sendbuf[BUFFER_SIZE]; char recvbuf[BUFFER_SIZE]; //至此就成功连接服务器了 int flag; while(1){ BeginPrompt(); fgets(sendbuf, sizeof(sendbuf), stdin); send(sock_cli, sendbuf, sizeof(sendbuf),0); ///发送 recv(sock_cli, recvbuf, sizeof(recvbuf),0); ///接收 if(strcmp(recvbuf,"register")==0){ int flag=-1; while(1){ flag=BeginWithRegis(sock_cli); if(flag==2) continue; else break; } if(flag==0) continue; else if(flag==-1) exit(1); else if(flag==1) break; } else if(strcmp(recvbuf,"login")==0){ int flag=-1; while(1){ flag=BeginWithLogin(sock_cli); if(flag==2) continue; else break; } if(flag==0) continue; else if(flag==1) break; else exit(1); } else exit(0); } } void ReadyPrompt() { puts("\n现在是准备阶段,你想要干什么?:\n"); puts("ready:准备游戏"); puts("logout:用户注销"); } void logout(int sock_cli) { char recvbuf[BUFFER_SIZE]; send(sock_cli, "userlogout", sizeof("userlogout"), 0); recv(sock_cli, recvbuf, sizeof(recvbuf),0); send(sock_cli, username, sizeof(username),0); recv(sock_cli, recvbuf, sizeof(recvbuf),0); if(strcmp(recvbuf, "successlogout")!=0) ERR_EXIT("logout error"); } int ready(int sock_cli){ char recvbuf[BUFFER_SIZE]; send(sock_cli, "clientready", sizeof("clientready"), 0); recv(sock_cli, recvbuf, sizeof(recvbuf),0); if(strcmp(recvbuf, "yourusername")==0 && strlen(username)>0){ //usrname should not be empty send(sock_cli, username, sizeof(username), 0); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf, "successready")==0) return 1; else ERR_EXIT("get ready error"); } else ERR_EXIT("username error"); } void UserGetReady(int sock_cli){ puts("你已经登录啦,现在准备进行游戏!-0-\n"); char choice2[30]; while(1) { ReadyPrompt(); fscanf(stdin, "%s", choice2); if(strcmp(choice2, "ready")==0){ int readyFlag=ready(sock_cli); if(readyFlag==1){ break; } else ERR_EXIT("ready error"); } if(strcmp(choice2, "logout")==0){ logout(sock_cli); puts("you have logout"); close(sock_cli); exit(0); } else{ puts("指令错误,请重新输入"); continue; } } } void WaitForOthers(int sock_cli){ char recvbuf[BUFFER_SIZE]; puts("wait for others...."); recv(sock_cli, recvbuf, sizeof(recvbuf),0); puts("allready"); memset(recvbuf, 0, sizeof(recvbuf)); // if(strcmp(recvbuf, "allready")!=0) // ERR_EXIT("ready error"); // } void UserCallLandlord(int sock_cli){ char recvbuf[BUFFER_SIZE], sendbuf[BUFFER_SIZE]; puts("call land lord now"); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf, "yourusername")!=0) ERR_EXIT("call username error"); send(sock_cli, username, sizeof(username), 0); puts("wait for others to CallLandlord"); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf, "calllandlord")==0){ while(1){ puts("call landlord or not ? (y/n)"); fscanf(stdin, "%s", sendbuf); if(strcmp(sendbuf, "y")==0 || strcmp(sendbuf, "n")==0){ send(sock_cli, sendbuf, sizeof(sendbuf), 0); break; } else{ puts(sendbuf); puts("input again"); continue; } } puts("wait for others to CallLandlord"); recv(sock_cli, landlord, sizeof(landlord), 0); printf("the landlord is %s\n", landlord); } } void ConnectServer(const int port){ puts("please wait 3 senconds"); for(int i=3;i>0;i--){ printf("%ds\n",i); sleep(1); } sock_cli = socket(AF_INET,SOCK_STREAM, 0); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); ///服务器端口 servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ///服务器ip int on = 1; if (setsockopt(sock_cli, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) ERR_EXIT("setsockopt error"); ///连接服务器,成功返回0,错误返回-1 if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) ERR_EXIT("connect error"); } void PlayGame(int sock_cli){ char recvbuf[BUFFER_SIZE], sendbuf[BUFFER_SIZE]; puts("game start"); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); if(strcmp(recvbuf, "yourusername")!=0) ERR_EXIT("call username error"); send(sock_cli, username, sizeof(username), 0); recv(sock_cli, recvbuf, sizeof(recvbuf), 0); puts(recvbuf); puts("wait for others..."); fgets(sendbuf, sizeof(sendbuf), stdin); send(sendbuf, ) } int main() { ConnectServer(MYPORT); UserBegin(sock_cli); UserGetReady(sock_cli); WaitForOthers(sock_cli); /*-----------------------------*/ ConnectServer(MYPORT2); UserCallLandlord(sock_cli); /*-----------------------------*/ ConnectServer(MYPORT3); PlayGame(sock_cli); close(sock_cli); return 0; }
usermysql.h
/* * 2014/9/13 * neverchanje */ #include <mysql/mysql.h> #include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> #include <queue> #include <string> using namespace std; const char server[] = "localhost"; const char user[] = "root"; const char password[] = "2610207wu"; const char database[] = "DDZ"; /* function list 1.UsernameExist 2.UserInsert 3.UserOnline 4.PasswordCorrect 5.StatusTurnOn 6.StatusTurnOff 7.StatusTurnReady :New! 8.SetLandlord :New! */ /* UsernameExit will return 3 kinds of values, -1 for error, 1 for username has already existed 0 for no such username */ int UsernameExist(char* un){ MYSQL *conn; MYSQL_RES *res; MYSQL_ROW row; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query,"SELECT COUNT(*) FROM users WHERE username=‘%s‘", un); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } res = mysql_use_result(conn); row = mysql_fetch_row(res); //row[0] is char if(atoi(row[0]) > 0){//this username has already exits return 1; } else return 0; mysql_free_result(res);//!!!you must free the result after a query mysql_close(conn); } /* UserInsert will return two kinds of values -1 for error, 1 for successful insert */ int UserInsert(char* un, char* pwd){ MYSQL *conn; MYSQL_RES *res; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1;; } sprintf(query,"INSERT INTO users(username, password)VALUES(‘%s‘,‘%s‘)", un, pwd); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } if(mysql_affected_rows(conn)==1){//sucessfully insert an user mysql_close(conn); return 1; } mysql_free_result(res); } int UserOnline(char* un){ MYSQL *conn; MYSQL_RES *res; MYSQL_ROW row; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query,"SELECT status FROM users WHERE username=‘%s‘ LIMIT 1", un); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } res = mysql_use_result(conn); row = mysql_fetch_row(res); if( strcmp(row[0], "online")==0 || strcmp(row[0], "ready")==0 ) return 1; else if( strcmp(row[0], "offline")==0 ) return 0; else{ fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } mysql_free_result(res); mysql_close(conn); } int PasswordCorrect(char* un, char* pwd){ MYSQL *conn; MYSQL_RES *res; MYSQL_ROW row; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query,"SELECT COUNT(*) FROM users WHERE username=‘%s‘ AND password=‘%s‘", un, pwd); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } res = mysql_use_result(conn); row = mysql_fetch_row(res); if( atoi(row[0])>0 ) return 1; else if( atoi(row[0])==0 ) return 0; else{ fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } mysql_free_result(res); mysql_close(conn); } int StatusTurnOn(char* un){ MYSQL *conn; MYSQL_RES *res; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query,"UPDATE users SET status=‘online‘ WHERE username=‘%s‘ LIMIT 1", un); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } if(mysql_affected_rows(conn)==1){//sucessfully insert an user return 1; } else{ fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } mysql_free_result(res); mysql_close(conn); } int StatusTurnOff(char* un){ MYSQL *conn; MYSQL_RES *res; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query,"UPDATE users SET status=‘offline‘ WHERE username=‘%s‘ LIMIT 1", un); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } if(mysql_affected_rows(conn)==1){//sucessfully insert an user mysql_close(conn); return 1; } else{ fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } } int StatusTurnReady(char * un){ MYSQL *conn; MYSQL_RES *res; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query,"UPDATE users SET status=‘ready‘, readytime=NOW() WHERE username=‘%s‘ LIMIT 1", un); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } if(mysql_affected_rows(conn)==1){//sucessfully insert an user mysql_close(conn); return 1; } else{ fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } } int SetLandlord(int gameID, const char* landlordname){ MYSQL *conn; MYSQL_RES *res; MYSQL_ROW row; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query, "UPDATE game SET landlord=‘%s‘ WHERE gameID=‘%d‘ LIMIT 1", landlordname, gameID); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } if(mysql_affected_rows(conn)==1){ mysql_close(conn); return 1; } } int InitUsers(int gameID, queue<string>& UserSequence){ MYSQL *conn; MYSQL_RES *res; MYSQL_ROW row; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query, "SELECT username FROM users WHERE status=‘ready‘ ORDER BY readytime ASC LIMIT 3"); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } res = mysql_use_result(conn); while( (row = mysql_fetch_row(res)) ) UserSequence.push(row[0]); mysql_free_result(res); mysql_close(conn); return 1; } int InitPlayer(int gameID, queue<string>& UserSequence){ MYSQL *conn; MYSQL_RES *res; MYSQL_ROW row; char query[100]; conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } sprintf(query, "SELECT username FROM users WHERE status=‘ready‘ ORDER BY readytime ASC LIMIT 3"); if (mysql_query(conn, query)) { fprintf(stderr, "%s\n", mysql_error(conn)); return -1; } res = mysql_use_result(conn); while( (row = mysql_fetch_row(res)) ){ if( strcmp(row[0], UserSequence.front().c_str())!=0 ) UserSequence.push(row[0]); } mysql_free_result(res); mysql_close(conn); return 1; }
poke.h
#include <iostream> #include <algorithm> #include <ctime> #include <cstdio> #include <string> #include <vector> #include <map> #include <queue> using namespace std; #define rep(i,x,y) for(int i=x;i<=y;i++) #define MAXLEN 1024 //客户端接受的字符串信息的长度 struct poke{ int flw, num; }p[55]; int index(int flw, int num){ if(flw==4) return 52+num; if(num>=3) return (num-3)*4+flw+1; if(num<3)//可省 return (10+num)*4+flw+1; } bool cmp(const poke& a, const poke& b){ return index(a.flw, a.num) < index(b.flw, b.num); } /*index 和 cmp用来排序*/ string s[55]={ "", "H.A", "H.2", "H.3", "H.4", "H.5", "H.6", "H.7", "H.8", "H.9", "H.10", "H.J", "H.Q", "H.K", "S.A", "S.2", "S.3", "S.4", "S.5", "S.6", "S.7", "S.8", "S.9", "S.10", "S.J", "S.Q", "S.K", "C.A", "C.2", "C.3", "C.4", "C.5", "C.6", "C.7", "C.8", "C.9", "C.10", "C.J", "C.Q", "C.K", "D.A", "D.2", "D.3", "D.4", "D.5", "D.6", "D.7", "D.8", "D.9", "D.10", "D.J", "D.Q", "D.K", "jkr", "JKR" }; //牌号下标从1开始,花色从0开始 //为了统一长度,我把jocker写成jkr /*s用来输出*/ void InitCards(){ rep(i,0,3){ rep(j,1,13){ int id=i*13+j; p[id].flw = i; p[id].num = j; } } p[53].flw=4;p[53].num=1;//小王 p[54].flw=4;p[54].num=2;//大王 } int a[55];//hash void ShuffleCards(){ srand(time(0)); rep(i,1,54) a[i] = i; for(int i=54;i>=1;i--) swap(a[i],a[rand()%i+1]); }//洗牌的复杂度为O(n) string getCards(int flw, int num){//H.7的flw=0, num=7 return s[flw*13+num]; } void setLandlordCards(string* landlordcards){ rep(i,1,3) landlordcards[i-1] = getCards(p[a[i]].flw, p[a[i]].num); } void dealCards(map< string, vector<poke> >& player, queue<string>& UserSequence){//发牌 string tmp = UserSequence.front(); rep(i,1,20) player[tmp].push_back(p[a[i]]); UserSequence.pop(); UserSequence.push(tmp); tmp=UserSequence.front(); rep(i,21,37) player[tmp].push_back(p[a[i]]); UserSequence.pop(); UserSequence.push(tmp); tmp=UserSequence.front(); rep(i,38,54) player[tmp].push_back(p[a[i]]); UserSequence.pop(); UserSequence.push(tmp); } void sortCards(vector<poke>& player){ sort( player.begin(), player.end(), cmp );//给p1的牌排序 } void printCards(vector<poke>& player){ for(int i=0; i<player.size(); i++){ cout<<getCards( player[i].flw, player[i].num ); if(i==player.size()-1) continue; if(player[i].num==10)//牌的间距是3格,有10的话间距会变成2格 printf(" "); else printf(" "); } puts(""); for(int i=0; i<player.size(); i++){ printf(" %d",i+1); if(i==player.size()-1) continue; if(i>=9) printf(" "); else printf(" "); } } string CardsToString(const vector<poke>& player){ string str; for(int i=0; i<player.size(); i++) str += " "+getCards(player[i].flw, player[i].num); } // /*以下是判牌操作*/ bool isNumeric(char x){ return x<=‘9‘ && x>=‘0‘; } void readGo(char* buf, vector<int>& v){//将指令转化为数组 v.clear();//先清空 int i=0; while(buf[i]!=‘\0‘){ if(!isNumeric(buf[i])){ i++; continue; } int x=buf[i]-‘0‘; if(isNumeric(buf[i+1])){ x = x*10+buf[i+1]-‘0‘; v.push_back(x); i+=2; } else{ v.push_back(x); i++; } } } void getGo(const vector<int>& v, const vector<poke>& player, vector<poke>& GoCards){//取得玩家的手牌,放在GoCards数组中 for(int i=0; i<v.size(); i++){ GoCards.push_back(player[v[i]-1]); } } /*读取指令*/ /*-----------------------------------------------------------------------------------*/ bool isSingle(vector<poke>& Go){ return Go.size()==1; } bool isSequence(vector<poke>& Go){ if(Go.size()<5) return 0; for(int i=1; i<Go.size(); i++){ if(Go[i].flw==4 || Go[i].num==2 || Go[i].num-Go[i-1].num!=1) //排除大小王 return 0; } return 1; } bool isTriple(vector<poke>& Go){ if(Go.size()!=3) return 0; return Go[0].num==Go[1].num && Go[1].num==Go[2].num; } int isTriple_One(vector<poke>& Go){ // if(Go.size()!=4) return 0; return (Go[0].num==Go[1].num && Go[1].num==Go[2].num) || (Go[1].num==Go[2].num && Go[2].num==Go[3].num); } bool isTriple_Two(vector<poke>& Go) //三张带一对 { if(Go.size()!=5) return 0; return (Go[0].num==Go[1].num && Go[1].num==Go[2].num) || (Go[2].num==Go[3].num && Go[3].num==Go[4].num); } bool isDsequence(vector<poke>& Go) //连对 { if(Go.size()<6||(Go.size()%2)!=0) return 0; for(int i=0,same=0;i<Go.size();i++) { if(Go[i].flw==4||Go[i].num==2) return 0; same=0; while(i<Go.size()-1 && Go[i].num==Go[i+1].num ) { same++; i++; } if(same!=1) return 0; if(i!=0&& i!=1 &&(Go[i].num-Go[i-2].num)!=1) return 0; } return 1; } bool isTriple_Ssequence(vector<poke>& Go) //三带一的顺子 { if(Go.size()<=4||Go.size()%4!=0) return 0; int same=0; int single=0; int triple=0; for(int i=0;i<Go.size();i++) { same=0; while(i<Go.size()-1 && Go[i].num==Go[i+1].num) { same++; i++; } if(same!=0&&same!=1&&same!=2) return 0; if(same==0) single++; if(same==1) single+=2; if(same==2) { if(Go[i].num==2) //三张不能出现2 return 0; else triple++; } } return single==triple; } bool isTriple_Dsequence(vector<poke>& Go) // 三张带一对的顺子 { if(Go.size()<=5||Go.size()%5!=0) return 0; int same=0; int couple=0; int triple=0; for(int i=0;i<Go.size();i++) { same=0; while(i<Go.size()-1 && Go[i].num==Go[i+1].num) { same++; i++; } if(same!=1&&same!=2) return 0; if(same==1) couple++; if(same==2) triple++; } return couple==triple; } bool isFour_Two_Differ(vector<poke>& Go) //四张带两张 { if(Go.size()!=6) return 0; int same=0; for(int i=0;i<Go.size();i++){ same=0; while( i<Go.size()-1 && Go[i].num==Go[i+1].num){ same++; i++; } if(same==3) return true; } return false; } bool isFour_Two_Same(vector<poke>& Go) //四张带两对 { if(Go.size()!=8) return 0; int couple=0; bool flag=false; for(int i=0,same=0;i<Go.size();i++){ same=0; while(i<Go.size()-1 && Go[i].num==Go[i+1].num ) { same++; i++; } if(same!=1 && same!=3) return 0; if(same==3) flag=true; if(same==1) couple++; } return couple==2 && flag; } bool isBomb(vector<poke>& Go) //炸弹(四张相同) { if(Go.size()!=4) return 0; return Go[0].num==Go[1].num && Go[1].num==Go[2].num && Go[2].num==Go[3].num; } bool isRocket(vector<poke>& Go) //火箭(大小王) { if(Go.size()!=2) return 0; return Go[0].flw==4 && Go[1].flw==4; } // int main(){ // vector<poke> player[3];//玩家一定是作为一个数组 // InitCards(); // ShuffleCards(); // dealCards(player); // sortCards(player[0]); // printCards(player[0]); // cout<<endl; // char buff[MAXLEN]; // vector<int> inputArr; // vector<poke> GoCards; // GoCards.clear(); // sortCards(GoCards); // cout<<isDsequence(GoCards); // return 0; // }
ubuntu的sublime没中文,没法写注释
有几个东西我说一下,最新加进了
在poke.h里面 string CardsToString(const vector<poke>& player){ string str; for(int i=0; i<player.size(); i++) str += " "+getCards(player[i].flw, player[i].num); } void setLandlordCards(string* landlordcards){ rep(i,1,3) landlordcards[i-1] = getCards(p[a[i]].flw, p[a[i]].num); } void dealCards(map< string, vector<poke> >& player, queue<string>& UserSequence){//发牌 string tmp = UserSequence.front(); rep(i,1,20) player[tmp].push_back(p[a[i]]); UserSequence.pop(); UserSequence.push(tmp); tmp=UserSequence.front(); rep(i,21,37) player[tmp].push_back(p[a[i]]); UserSequence.pop(); UserSequence.push(tmp); tmp=UserSequence.front(); rep(i,38,54) player[tmp].push_back(p[a[i]]); UserSequence.pop(); UserSequence.push(tmp); }
server的公共变量放在头部,可以去看
usersquence 用queue实现,表示用户的队列,用于抢地主和游戏过程
typedef map< string,vector<poke> > PLAYERLIST;
PLAYERLIST player;
指的是用map实现,就是利用用户的名字作为索引,本质跟我之前的vector<poke> player[3]是一样的
server暂时利用三个多线程,登陆注册一次,叫地主一次,游戏又一次
游戏过程中要使得另外两方暂停用的是语句
while(usersequence.front()!=usernow) sleep(3);
usermysql增加了函数inituser和initplayer,分别用于初始化抢地主时的用户顺序,游戏过程的用户顺序。
注意的是游戏过程的用户顺序会因为炸弹改变。
标签:style blog http color io os ar for 2014
原文地址:http://www.cnblogs.com/neverchanje/p/3977054.html