首页 > 代码库 > 斗地主
斗地主
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 list1.UsernameExist2.UserInsert3.UserOnline4.PasswordCorrect5.StatusTurnOn6.StatusTurnOff7.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];//hashvoid 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,分别用于初始化抢地主时的用户顺序,游戏过程的用户顺序。
注意的是游戏过程的用户顺序会因为炸弹改变。
斗地主
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。