码迷,mamicode.com
首页 > 其他好文 > 详细

斗地主

时间:2014-09-17 15:02:22      阅读:409      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   2014   

server.cpp

bubuko.com,布布扣
#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

bubuko.com,布布扣
#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

bubuko.com,布布扣
/*
 * 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;
}
View Code

poke.h

bubuko.com,布布扣
#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;
// }
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,分别用于初始化抢地主时的用户顺序,游戏过程的用户顺序。

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

 

斗地主

标签:style   blog   http   color   io   os   ar   for   2014   

原文地址:http://www.cnblogs.com/neverchanje/p/3977054.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!