2022年 11月 9日

python虚拟宠物猫

import threading
import numpy

pConData = numpy.load('pData.npy')
pConSta = numpy.load('pSta.npy')
exec_count = pConData[3]
# exec_count = 0
judgeStop = False


def rangeData(num):  # 各指数的值在 0~100之间

    if num > 100:
        num = 100
        pass
    elif num < 0:
        num = 0
        pass
    return num
    pass


def Clock():  # 模拟24h的时钟
    global exec_count
    global judgeStop
    # print("当前时刻:{}点".format(exec_count))

    # 8点醒0点睡
    if exec_count == 0:
        p.sleep()
        pass
    elif exec_count == 8:
        p.wake()
        pass

    # 在醒着,什么事都不做的情况下,每个滴答,饥饿指数增加 2,幸福指数减少 1
    # 在睡着状态,每个滴答,饥饿指数增加 1
    # 如果在睡觉状态,你要带它去活动,需要提醒,如果你坚持要带它去活动,幸福指数将减去 4
    # 在陪它散步状态,每个滴答,饥饿指数增加 3, 健康指数加 1
    # 在陪它玩耍状态,每个滴答,饥饿指数增加 3,幸福指数增加 1
    # 在喂食状态:每个滴答,饥饿指数则减少 3
    # 如果带它去看医生,则每个滴答,健康指数将增加 4

    if p.status == "我在散步...":  # 判断放在时钟里 可以每小时判断一次状态改变参数
        p.Hungry += 3
        p.Health += 1
        pass
    elif p.status == "我在玩耍...":
        p.Hungry += 3
        p.Happiness += 1
        pass
    elif p.status == "我在吃饭...":
        p.Hungry -= 3
        pass
    elif p.status == "我在看医生...":
        p.Health += 4
        pass
    elif p.status == "我在睡觉...":
        p.Hungry += 1
        pass
    elif p.status == "我醒着但我很无聊...":
        p.Hungry += 2
        p.Happiness -= 1
        pass

    if p.status != "我在睡觉..." and exec_count < 8:
        p.Happiness -= 4
        pass

    # 如果饥饿指数在大于 80,或低于 20 即过饱,则每个滴答,健康指数将减去 2
    # 如果幸福指数低于 20,则每个滴答,健康指数将减去 1
    if p.Happiness < 20:
        p.Health -= 1
        pass

    if p.Hungry > 80 or p.Hungry < 20:
        p.Health -= 2
        pass

    # 改变值之后判断是否超过范围
    p.Hungry = rangeData(p.Hungry)
    p.Health = rangeData(p.Health)
    p.Happiness = rangeData(p.Happiness)

    exec_count += 1  # 计数加一

    # 当时间计数到23时归零,循环输出时间

    if judgeStop == False:
        if exec_count < 24:
            threading.Timer(5, Clock).start()
            pass
        else:
            exec_count = 0
            threading.Timer(1, Clock).start()
            pass
        pass
    pass



def printInfo(a):  # 按照进度表输出参数
    for i in range(1, (int)(a/2)+1):
        print("*", end="")
        pass

    for i in range((int)(a/2)+1, 51):
        print("-", end="")
        pass
    pass


class Pet:

    def __init__(self, Happiness, Hungry, Health, status):  # 初始化参数

        self.name = "Tommy"
        self.Happiness = Happiness
        self.Hungry = Hungry
        self.Health = Health
        self.status = status
        pass

    def sleep(self):
        self.status = "我在睡觉..."
        # print(self.status)
        pass

    def wake(self):
        self.status = "我醒着但我很无聊..."
        # print(self.status)
        pass

    def walk(self):
        self.status = "我在散步..."
        print(self.status)
        pass

    def play(self):
        self.status = "我在玩耍..."
        print(self.status)
        pass

    def feed(self):
        self.status = "我在吃饭..."
        print(self.status)
        pass

    def seeDoctor(self):
        self.status = "我在看医生..."
        print(self.status)
        pass


    # 当你键入“status“命令时,需要你用”*“和”-“字符(共计 50 个)模拟
    # 它的状态进度度,并给出当前状态指数的具体值。
    def cur_status(self):
        print("\n当前时间:", end="")
        print("{}点".format(exec_count))
        print("我当前的状态:", end="")
        print(self.status)
        print("Happiness:   Sad", end="")
        printInfo(self.Happiness)
        print("Happy({})".format(self.Happiness))

        print("Hungry:      Full", end="")
        printInfo(self.Hungry)
        print("Hungry({})".format(self.Hungry))

        print("Health:      Sick", end="")
        printInfo(self.Health)
        print("Healthy({})\n".format(self.Health))
        pass
    pass

# 加载参数

# p = Pet(0, 0, 0 ,"")


p = Pet(pConData[0], pConData[1], pConData[2], pConSta[0])


def orderWakePet(order):  # 宠物醒着的时候,运行命令
    if order == "walk":
        p.walk()
        pass
    elif order == "play":
        p.play()
        pass
    elif order == "feed":
        p.feed()
        pass
    elif order == "see doctor":
        p.seeDoctor()
        pass
    elif order == "letalone":
        p.wake()
        print(p.status)
        pass
    else:
        print("我不懂你在说什么")
        pass


def orderSleepPet(order):  # 宠物睡着的时候,先确定是否叫醒,再运行命令
    if order == "letalone":
        p.sleep()
        print(p.status)
        pass
    else:
        ans = input("你确定要吵醒我吗?我在睡觉,你要是坚持吵醒我,我会不高兴的!(y表示是/其他表示不是)")
        if ans == 'y':
            if order == "walk":
                p.walk()
                pass
            elif order == "play":
                p.play()
                pass
            elif order == "feed":
                p.feed()
                pass
            elif order == "see doctor":
                p.seeDoctor()
                pass
            else:
                print("我不懂你在说什么")
                pass
            pass


def mainF():
    global judgeStop
    while True:
        a = input("你想做什么")
        if a == "bye":
            # 存储参数
            # 当你键入“bye”暂时关闭程序,你需要将 Tommy 的状态保存到文件(包括
            # 当前时刻,当前所处的状态,睡觉、散步等,各个状态指数),以便重新开始
            # 程序时,可以接着上次的状态开始你的游戏
            pData = [p.Happiness, p.Hungry, p.Health, exec_count]
            pSta = [p.status]
            numpy.save('pData.npy', pData)
            numpy.save('pSta.npy', pSta)
            print("记得来找我!Bye...")
            judgeStop = True
            break
        elif a == "status":
            p.cur_status()
            pass
        else:
            if exec_count >= 8:  # 8点到24点
                orderWakePet(a)
                pass
            else:  # 0点到8点
                orderSleepPet(a)
                pass
    pass


def VirtualPet():
    print("我的名字叫Tommy,一只可爱的猫咪....")
    print("你可以和我一起散步玩耍,你也可以给我好吃的东西,带我去看病,也可以让我发呆....")
    print("Commands:")
    print("1.walk:散步")
    print("2.play:玩耍")
    print("3.feed:喂我")
    print("4.see doctor:看医生")
    print("5.letalone:让我独自一人")
    print("6.status:查看我的状态")
    print("7.bye:不想看到我\n")
    t1 = threading.Thread(target=Clock)
    t2 = threading.Thread(target=mainF)
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    pass


if __name__ == '__main__':
    VirtualPet()
    pass



这里我是直接建立了两个文件来存储数据。如果没有创建文件且初始化数据直接运行会报错。正规的写法是类似于类的单例模式,即程序一开始判断是否有存储数据的文件,如果没有就创建并赋初始值再调用里面的数,如果有的话就直接调用里面的数据就可以了。
因为很多人询问,我就放在下面了,也就是将开头的直接读取
pConData = numpy.load('pData.npy')
pConSta = numpy.load('pSta.npy')
这里修改一下:
import os.path
if(os.path.exists('D:/python/practice/VirtualPet/pSta.npy') and os.path.exists('D:/python/practice/VirtualPet/pData.npy')):
    pConData = numpy.load('pData.npy')
    pConSta = numpy.load('pSta.npy')
    pass
else:
    pData = [100, 0, 100, 0]
    pSta = ['我在睡觉...']
    numpy.save('pData.npy', pData)
    numpy.save('pSta.npy', pSta)
    pConData = numpy.load('pData.npy')
    pConSta = numpy.load('pSta.npy')
    pass
当然,我这里是直接同时判断两个文件是否存在,单独判断更严谨吧可能。另外如果不是使用numpy格式的文件保存(我是因为方便),而是使用txt之类的,那就要使用文件读取方面的内容了(with open等),读取的时候记得格式是字符串还是整型之类的,其他就没什么问题了。

将开头改为这个就能直接运行不报错,当然你要自定义自己保存的路径。