TCP交互式游戏《基于TCP的C/S程序设计》

杭电胡老师的实验三:

要求:
通过在远端主机上搭建一个远程骰宝服务器,其它主机可以通过客户端程序
RemoteBet与远程的骰宝服务器联系,进行交互式游戏设计。命令行格式如下:
RemoteBet
如: RemoteBet 127.0.0.1
规则如下:
ya tc <数量> 押头彩(两数顺序及点数均正确) 一赔三十五
ya dc <数量> 押大彩(两数点数正确) 一赔十七
ya kp <数量> 押空盘(两数不同且均为偶数) 一赔五
ya qx <数量> 押七星(两数之和为七) 一赔五
ya dd <数量> 押单对(两数均为奇数) 一赔三
ya sx <数量> 押散星(两数之和为三、五、九、十一) 一赔二
每盘按从上到下的顺序只出现一种点型(头彩和大彩可同时出现),其他情况都算庄家赢。
庄家唱道:新开盘!预叫头彩!
庄家将两枚玉骰往银盘中一撒。
┌───┐ ┌───┐
│● ● │ │ │
│● ● │ │ ● │
│● ● │ │ │
└───┘ └───┘
庄家唱道:头彩骰号是六、一!
输入你压的值:
ya tc 10 gold
庄家将两枚玉骰扔进两个金盅,一手持一盅摇将起来。
庄家将左手的金盅倒扣在银盘上,玉骰滚了出来。
┌───┐
│● ●│
│ ● │
│● ●│
└───┘
庄家将右手的金盅倒扣在银盘上,玉骰滚了出来。
┌───┐
│ ● │
│ │
│ ● │
└───┘
庄家叫道:五、二……七星。
你赢了多少?or 你输了多少?

假设服务器的IP地址为127.0.0.1,客户端程序连接到服务器进行远程骰宝游戏,然后按照服务器发回的游戏规则和提示进行游戏。
·
·
·
·
·
我用协程做的,使用时要导入gevent这个包

游戏服务器:

"""
@author: Bre Athy
@contact: https://www.zhihu.com/people/you-yi-shi-de-hu-xi
@productware: PyCharm
@file: 游戏服务器.py
@time: 2019/11/10 23:40
"""
import socket,json,random,gevent
from gevent import monkey

users=[]

# 初始钱币
thecoin=thesilver=thegold=30
def service_client(new_socket):
    def sendToClient(dict_info):
        new_socket.send(json.dumps(dict_info).encode("utf-8"))

    # 接收请求
    while True:
        recv_data=new_socket.recv(1024).decode("utf-8")
        data=json.loads(recv_data)
        print(data)
        dice1, dice2 = random.randint(1, 6), random.randint(1, 6)
        if data['alt']=="游戏开始":
            uid=len(users)
            user={"uid":uid,"coin":thecoin,"silver":thesilver,"gold":thegold,'dice1':dice1,'dice2':dice2}
            users.append({"uid":uid,"money":thecoin+thesilver*100+thegold*10000,"dice1":dice1,"dice2":dice2})
            sendToClient(user)
        elif data['alt']=="压注":
            bet=True
            if data['type']=='tc' and dice1==data['dice1'] and dice2==data['dice2']:users[data["uid"]]["money"]+=data['money']*35
            elif data['type']=='dc' and ((dice1==data['dice1'] and dice2==data['dice2']) or (dice1==data['dice2'] and dice2==data['dice1'])):users[data["uid"]]["money"]+=data['money']*17
            elif data['type']=='kp' and (dice1!=dice2 and dice1%2==0 and dice2%2==0):users[data["uid"]]["money"]+=data['money']*5
            elif data['type']=='qx' and dice1+dice2==7 :users[data["uid"]]["money"]+=data['money']*5
            elif data['type']=='dd' and dice1%2==1 and dice2%2==1:users[data["uid"]]["money"]+=data['money']*3
            elif data['type']=='sx' and dice1+dice2 in [3,5,9,11]:users[data["uid"]]["money"]+=data['money']*2
            else:
                users[data['uid']]['money']-=data['money']
                bet=False
            sendToClient({'dice1':dice1,'dice2':dice2,'bet':bet})
        elif data['alt']=="新开盘":
            users[data['uid']]['dice1']=dice1
            users[data['uid']]['dice2']=dice2
            sendToClient({'dice1':dice1,'dice2':dice2})
        else:
            print("信息有误!出错内容:%s"%data)


def main():
    "服务器基本功能"
    monkey.patch_all()
    # 创建套接字
    tcp_sever_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 绑定端口
    tcp_sever_socket.bind(("",6666))
    # 准备监听
    tcp_sever_socket.listen(128)

    while True:
        # 等待客户端链接
        new_socket,client_addr=tcp_sever_socket.accept()
        # 为客户端服务
        gevent.spawn(service_client,new_socket)


if __name__ == "__main__":
    main()

游戏客户端:

"""
@author: Bre Athy
@contact: https://www.zhihu.com/people/you-yi-shi-de-hu-xi
@productware: PyCharm
@file: 游戏客户端.py
@time: 2019/11/10 23:40
"""
import socket,json,time
TZ=[
    """
┌────────┐
│        │
│   ●    │
│        │
└────────┘""",
    """
┌────────┐
│   ●    │
│        │
│   ●    │
└────────┘""",
    """
┌────────┐
│    ●   │
│        │
│ ●    ● │
└────────┘""",
    """
┌────────┐
│ ●    ● │
│        │
│ ●    ● │
└────────┘""",
    """
┌────────┐
│ ●    ● │
│   ●    │
│ ●    ● │
└────────┘""",
    """
┌────────┐
│  ●  ●  │
│  ●  ●  │
│  ●  ●  │
└────────┘"""
]
alb=['〇','一','二','三','四','五','六']

c_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
info={}
addr=("127.0.0.1",6666)

def sendAndWait(dict_info):
    "传进来一个字典自动发送,返回一个字典"
    info=json.dumps(dict_info).encode("utf-8")
    c_socket.send(info)
    recv_data=c_socket.recv(1024).decode("utf-8")
    return json.loads(recv_data)

def getInfo():
    print("当前coin:%d  silver:%d  gold:%d"%(info['coin'],info['silver'],info['gold']))


def myprint(words,thetime):
    print(words)
    time.sleep(thetime)


def main():
    global addr
    print("★"*8,"欢迎体验骰宝游戏","★"*8)
    while True:
        print("请按 括号内提示 输入服务器地址启动游戏 :")
        addr=(input()[10:],6666)
        # addr=("127.0.0.1",6666)
        print("连接服务器ing...")
        try:
            c_socket.connect(addr)
            break
        except:
            print("连接服务器失败,你输入的IP地址为: %s 请重新输入!"%addr[0])
    global info
    info={"alt":"游戏开始"}
    info=sendAndWait(info)
    print("★"*8,"游戏开始","★"*8)
    print("★"*4,"输入 Help 查看游戏帮助","★"*4)
    getInfo()
    myprint("进入赌场,你走进了一张桌子......",3)
    myprint("庄家唱到:新开盘!预叫头彩!",2)
    myprint("庄家将两枚玉骰往银盘中一撒。",2)
    myprint(TZ[int(info['dice1'])-1],1)
    myprint(TZ[int(info['dice2'])-1],1)
    myprint("庄家唱道:头彩骰号是%s、%s!"%(alb[int(info['dice1'])],alb[int(info['dice2'])]),2)
    while True:
        print("请下注:")
        cmd=input().lower()
        # 帮助
        if cmd == "help":
            help="""★★★★★★★★游戏帮助★★★★★★★★
新开盘: new
查看余额:ye
钱币转换:zh <数量>  to      金:银:硬=1:100:10000   
ya tc <数量>  押头彩(两数顺序及点数均正确)        一赔三十五
ya dc <数量>  押大彩(两数点数正确)               一赔十七
ya kp <数量>  押空盘(两数不同且均为偶数)          一赔五
ya qx <数量>  押七星(两数之和为七)               一赔五
ya dd <数量>  押单对(两数均为奇数)               一赔三
ya sx <数量>  押散星(两数之和为三、五、九、十一)  一赔二
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"""
            print(help)
        # 新开盘
        elif cmd =="new":
            myprint("你离开了这个赌局,换到了新的一桌",3)
            info['alt']="新开盘"
            ret=sendAndWait(info)
            info['dice1'],info['dice2']=ret['dice1'],ret['dice2']
            myprint("庄家唱道:这位爷留步: 新开盘!预叫头彩!", 2)
            myprint("你停了下来,定睛看去,", 3)
            myprint("庄家慢慢将两枚玉骰往银盘中一撒。", 2)
            myprint(TZ[info['dice1'] - 1], 1)
            myprint(TZ[info['dice2'] - 1], 1)
            myprint("庄家唱道:头彩骰号是%s、%s!" % (alb[int(info['dice1'])], alb[int(info['dice2'])]), 2)
        # 查看余额
        elif cmd == "ye":getInfo()
        # 个人信息
        elif cmd == "@@@":print(info)
        # 下注
        elif len(cmd.split(" "))==4:
            try:
                a, b, c, d=tuple(cmd.split(" "))
                assert a=="ya"
                assert b in ['tc','dc','kp','qx','dd','sx']
                if not c.isdigit():raise ValueError
                assert d in ['gold','coin','silver']
            except:print("输入有误! 请重新输入!<输入 Help 查看游戏帮助>")
            else:
                if int(c) > info[d]:
                    print("你没有那么多 %s!"%(d[0].upper()+d[1:]))
                    continue
                info['money']=int(c) if d=='coin' else (int(c)*100 if d=='silver' else int(c)*10000)
                info['alt']='压注'
                info['type']=b
                ret=sendAndWait(info)
                d1,d2=ret['dice1'],ret['dice2']
                if ret['bet']:
                    if b=='tc':info[d]+=int(c)*35
                    elif b=='dc':info[d]+=int(c)*17
                    elif b=='kp':info[d]+=int(c)*5
                    elif b=='qx':info[d]+=int(c)*5
                    elif b=='dd':info[d]+=int(c)*3
                    elif b=='sx':info[d]+=int(c)*2
                else:info[d]-=int(c)
                if d=='gold':gu="金蛊"
                elif d=='silver':gu="银蛊"
                else:gu='铜蛊'
                myprint("庄家将两枚玉骰扔进两个%s,一手持一盅摇将起来。"%gu,3)
                myprint("庄家将左手的%s倒扣在银盘上,玉骰滚了出来。"%gu,2)
                myprint(TZ[d1-1],2)
                myprint("庄家将右手的%s倒扣在银盘上,玉骰滚了出来。"%gu,2)
                myprint(TZ[d2-1],3)
                rs="庄赢"
                if d1+d2 in [3,5,9,11]:rs="散星"
                if d1%2==1 and d2%2==1:rs="单对"
                if d1+d2==7:rs="七星"
                if d1!=d2 and d1%2==0 and d2%2==0:rs="空盘"
                if (d1==info['dice1'] and d2==info['dice2']) or (d1==info['dice2'] and d2==info['dice1']):rs="大彩"
                if d1==info['dice1'] and d2==info['dice2']:rs="头彩"
                myprint("庄家叫道:%s、%s······%s。"%(alb[d1],alb[d2],rs),3)
                if ret['bet']:
                    myprint("庄家唱道:恭喜恭喜这位爷,赢了%s!"%rs,3)
                else:myprint("没压中,哎呀",2)

        # 钱币转换
        elif len(cmd.split(" "))==5:
            try:
                a, money, c, d ,e = tuple(cmd.split(" "))
                assert a == "zh"
                if not money.isdigit():raise ValueError
                assert c in ['gold','silver','coin']
                assert d == "to"
                assert e in ['gold','silver','coin']
            except:print("输入有误! 请重新输入!<输入 Help 查看游戏帮助>")
            else:
                if int(money) > info[c]:
                    print("你没有那么多 %s!"%(c[0].upper()+c[1:]))
                    continue
                if c == e:
                    print("转换成功!当前余额:")
                    getInfo()
                elif (c == 'gold' and e =='silver') or (c == 'silver' and e == 'coin'):
                    info[c]-=int(money)
                    info[e]+=int(money)*100
                    print("转换成功!当前余额:")
                    getInfo()
                elif (c == 'silver' and e =='gold') or (c == 'coin' and e == 'silver'):
                    if int(money)%100!=0:
                        print("转换失败 ! 请输入100的倍数!")
                        continue
                    info[c]-=int(money)
                    info[e]+=int(money)//100
                    print("转换成功!当前余额:")
                    getInfo()
                elif c == 'coin' and e =='gold':
                    if int(money)%10000!=0:
                        print("转换失败 ! 请输入10000的倍数!")
                        continue
                    info[c]-=int(money)
                    info[e]+=int(money)//10000
                    print("转换成功!当前余额:")
                    getInfo()
                else:
                    info[c]-=int(money)
                    info[e]+=int(money)*10000
                    print("转换成功!当前余额:")
                    getInfo()
        else:print("输入有误! 请重新输入!<输入 Help 查看游戏帮助>")



if __name__ == "__main__":
    main()

你可能感兴趣的:(Python网络编程)