首页 > 代码库 > 斗地主

斗地主

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;}
View Code

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;}
View Code

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;}
View Code

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;// }
View Code

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,分别用于初始化抢地主时的用户顺序,游戏过程的用户顺序。

注意的是游戏过程的用户顺序会因为炸弹改变。

 

斗地主