恶魔之轮 11.0 预备版本
2025-04-08 17:58:49
发布于:浙江
PY的代码(还未完善)
import logging
from flask import Flask, render_template, request, jsonify, make_response
import threading
import time
import random
import string
import sys
import os
from werkzeug.serving import make_server
app = Flask(__name__)
# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 存储用户信息,格式:{用户ID: [用户名, 密码, 分数, 关注列表, 粉丝列表]}
users = {}
# 存储在线玩家的连接
online_players = {}
# 存储等待匹配的玩家
waiting_players = []
# 游戏状态枚举
GAME_STATE_WAITING = "WAITING"
GAME_STATE_STARTED = "STARTED"
GAME_STATE_ENDED = "ENDED"
# Flask 服务器对象
server = None
def generate_id():
return ''.join(random.choices(string.digits, k=10))
def save_users():
"""保存用户信息到文件"""
try:
with open('users.txt', 'w') as f:
for user_id, info in users.items():
follow_list_str = '|'.join(info[3])
follower_list_str = '|'.join(info[4])
f.write(f"{user_id},{info[0]},{info[1]},{info[2]},{follow_list_str},{follower_list_str}\n")
except Exception as e:
logging.error(f"保存用户信息时出错: {e}")
def load_users():
global users
users = {}
try:
with open('users.txt', 'r') as f:
for line in f:
line = line.strip()
if not line:
continue
parts = line.split(',')
if len(parts) < 6:
logging.warning(f"Invalid line in users.txt: {line}")
continue
user_id = parts[0]
username = parts[1]
password = parts[2]
score = int(parts[3])
follow_list = parts[4].split('|') if parts[4] else []
follower_list = parts[5].split('|') if parts[5] else []
users[user_id] = [username, password, score, follow_list, follower_list]
except FileNotFoundError:
pass
def slow_print(text):
for char in text:
print(char, end='', flush=True)
time.sleep(0.02)
print()
def introduce_rules():
"""介绍游戏规则"""
rules = []
rules.append("🎉欢迎来到恶魔之轮游戏!以下是游戏规则:")
rules.append("1. 本游戏有两种模式:玩家对战和人机对战,双方初始血量均为5点😎。")
rules.append("2. 游戏开始时,每位玩家会随机获得3种不同的道具,每轮结束后,每位玩家再随机获得2种道具🎁。")
rules.append("3. 道具及作用:")
rules.append(" - 小烟:使用后可恢复1点血量💊。")
rules.append(" - 放大镜:使用后能查看下一发子弹是实弹还是空弹🔍。")
rules.append(" - 扳手:使用后直接对对手造成1点伤害🔧。")
rules.append(" - 小刀:若下一发为实弹,使用时伤害额外加1,即造成2点伤害;若为空弹,仅造成1点伤害🔪。")
rules.append(" - 手雷:范围伤害,可使所有玩家血量 - 3💣。")
rules.append(" - 盾牌:可免疫50%的伤害,价格:3枚金币🛡️。")
rules.append(" - 剑:使伤害增加10%,价格:4枚金币🗡️。")
rules.append(" - 伤害药水:下一次攻击伤害翻倍,价格:5枚金币🧪。")
rules.append(" - 手铐:使对手下一轮直接跳过,价格:3枚金币🪤。")
rules.append(" - 机器人:召唤一个助手,目标始终为召唤人的对手,不会攻击恶魔,1轮后消失,价格:6枚金币🤖。")
rules.append("4. 游戏中会随机生成实弹和空弹,两者数量之和为10🎯。")
rules.append("5. 实弹射击可扣减对手1滴血,空弹射击无伤害,射击一次对应子弹数量减1🔫。")
rules.append("6. 每轮玩家可以选择射击、使用道具或跳过本轮,使用完道具后仍可继续操作🎮。")
rules.append("7. 玩家现在可以选择射击自己🤔。")
rules.append("8. 当一方玩家的血量归零,则该玩家输掉游戏😢。")
rules.append("9. 如果实弹和空弹数都为0,则恶魔开始行动,行动前,实弹数恢复成10,空弹数为0👿。")
rules.append(" - 恶魔可以随机攻击玩家一或玩家二。")
rules.append(" - 玩家一、二也可以选择攻击彼此或恶魔。")
rules.append(" - 恶魔行动重复5次后轮到玩家一、玩家二,玩家二弄完后继续轮到恶魔,直至只剩下1个人存活。")
rules.append(" - 死去的玩家不可以继续操作😵。")
rules.append("10. 在执行完3或4轮后开始小游戏时间🎮:")
rules.append(" - 恶魔大战:一旦开始,两位玩家则收到3滴血的伤害,执行完1轮后退出😈。")
rules.append(" - 菜鸟互啄:玩家每次可以执行两个操作,操作1:防御盾,可以免疫一次伤害;操作2:啄啄,可以直接对对手造成2滴伤害,执行完2轮后退出🐤。")
rules.append(" - 双枪设计:游戏时,玩家手上的枪增加一把,同时射出的子弹数量也为二,其余规则和普通一致,执行完1轮后跳出🔫🔫。")
rules.append(" - 趣味躲靶:两位玩家依次选择往上、下、左、右躲避,此时会有一个恶魔,随机往三个方向射出子弹,如果玩家的躲避方向和恶魔子弹射出的方向中的任何一个相同则血量 - 2😨。")
rules.append("11. 游戏中可以获得金币,金币可用于购买道具。每轮玩家有50%的概率获得1 - 3枚金币💰。")
rules.append("后续情节规则:")
rules.append("在恶魔之轮游戏中玩家胜利后,将解锁新的情节:")
rules.append("神秘信使:玩家在游戏中偶然遇到一个神秘的信使,他带着一封来自未知发件人的信件📨。信件内容暗示了恶魔之轮背后隐藏着一个更大的阴谋,而玩家被选中来揭开这个秘密。信使会在特定的地点和时间出现,引导玩家完成一系列任务,以获取更多关于阴谋的线索。这些任务可能包括在危险的区域寻找古老的符文,或者与隐藏在暗处的神秘人物交流🕵️。")
rules.append("记忆碎片:玩家在探索恶魔之轮的世界时,会发现一些神秘的记忆碎片🧩。这些碎片属于一个曾经试图阻止恶魔之轮转动的英雄,但他的记忆被邪恶力量分割。玩家需要收集这些碎片,每收集一片,就会解锁一段关于这位英雄的回忆,包括他与恶魔的战斗、与同伴的合作以及最终失败的原因。通过这些回忆,玩家可以了解到更多关于恶魔之轮的历史和弱点,同时也能发现一些隐藏的线索,帮助他们在游戏中取得进展🌟。")
rules.append("隐藏教派:在游戏世界中,玩家发现了一个隐藏的教派,他们秘密崇拜着恶魔之轮的力量😈。这个教派的成员分散在各个角落,通过秘密仪式和符号来传递信息。玩家需要深入调查这个教派,了解他们的目的和计划。在调查过程中,玩家可能会遇到教派的守护者,他们会阻止玩家的行动。玩家需要通过解谜、战斗等方式来突破他们的防线,最终揭露教派的秘密,这可能会导致玩家与教派的首领展开一场惊心动魄的对决⚔️。")
rules.append("时空裂缝:在游戏的某个关键节点,玩家触发了一个神秘的事件,导致时空裂缝出现🕳️。这些裂缝连接着不同的时间和空间,里面隐藏着各种危险和机遇。玩家可以选择进入裂缝,探索不同的世界,每个世界都有独特的敌人、宝藏和任务。在裂缝中,时间的流动可能会变得异常,玩家需要适应这种变化,同时利用裂缝中的特殊环境来解决谜题和战胜敌人。通过探索时空裂缝,玩家可以获得强大的道具和技能,这些将有助于他们在恶魔之轮的挑战中取得优势💪。")
rules.append("同伴背叛:玩家在游戏中结识了一位强大的同伴,他们一起并肩作战,共同面对恶魔之轮带来的挑战🤝。然而,在游戏的某个关键时刻,同伴突然背叛了玩家,原来他被恶魔的力量所诱惑,企图利用玩家来获取恶魔之轮的控制权😡。玩家需要在被背叛的困境中寻找出路,一方面要躲避同伴的追杀,另一方面要揭露他的阴谋并阻止他。在这个过程中,玩家可能会发现同伴背叛的背后还有更深层次的原因,这将使玩家陷入道德和情感的困境,同时也增加了游戏的剧情深度和紧张感😭。")
rules.append("注意:有任意一个情节失败则整个游戏结束❗。")
return rules
class Game:
def __init__(self, player1_id, player2_id):
self.player1 = {
"name": users[player1_id][0],
"health": 5,
"items": self.get_random_items(),
"coins": 0,
"state": GAME_STATE_STARTED
}
self.player2 = {
"name": users[player2_id][0],
"health": 5,
"items": self.get_random_items(),
"coins": 0,
"state": GAME_STATE_STARTED
}
self.real_count, self.empty_count = self.generate_bullets()
self.round_num = 0
def get_random_items(self):
"""随机获取3种不同道具"""
all_items = ["小烟", "放大镜", "扳手", "小刀", "手雷", "盾牌", "剑", "伤害药水", "手铐", "机器人"]
return random.sample(all_items, 3)
def add_random_items(self, player):
"""每轮结束后为玩家随机添加2种道具"""
all_items = ["小烟", "放大镜", "扳手", "小刀", "手雷", "盾牌", "剑", "伤害药水", "手铐", "机器人"]
player["items"].extend(random.choices(all_items, k=2))
def generate_bullets(self):
"""随机生成实弹和空弹数量,总和为10"""
real_count = random.randint(1, 9)
empty_count = 10 - real_count
return real_count, empty_count
def shoot(self, shooter, target):
if self.real_count + self.empty_count == 0:
return {"status": "NO_BULLETS"}
if random.random() < self.real_count / (self.real_count + self.empty_count):
damage = 1
target["health"] = max(0, target["health"] - damage)
self.real_count -= 1
return {"status": "SHOOT_REAL", "shooter": shooter["name"], "target": target["name"], "damage": damage,
"target_health": target["health"]}
else:
self.empty_count -= 1
return {"status": "SHOOT_EMPTY", "shooter": shooter["name"]}
def use_item(self, player, opponents):
items = player["items"]
if not items:
return {"status": "ITEM_USED", "player": player["name"], "message": "NO_ITEMS"}
item = items.pop(0)
if item == "小烟":
player["health"] = min(player["health"] + 1, 5)
return {"status": "ITEM_USED", "player": player["name"], "item": "小烟", "effect": "HEALED",
"player_health": player["health"]}
elif item == "放大镜":
next_is_real = random.random() < self.real_count / (self.real_count + self.empty_count)
bullet_type = "实弹" if next_is_real else "空弹"
return {"status": "ITEM_USED", "player": player["name"], "item": "放大镜", "effect": "NEXT_BULLET",
"bullet_type": bullet_type}
elif item == "扳手":
target = random.choice([opp for opp in opponents if opp["health"] > 0])
target["health"] = max(0, target["health"] - 1)
return {"status": "ITEM_USED", "player": player["name"], "item": "扳手", "target": target["name"],
"effect": "DAMAGED", "damage": 1, "target_health": target["health"]}
elif item == "小刀":
target = random.choice([opp for opp in opponents if opp["health"] > 0])
if random.random() < self.real_count / (self.real_count + self.empty_count):
damage = 2
else:
damage = 1
target["health"] = max(0, target["health"] - damage)
return {"status": "ITEM_USED", "player": player["name"], "item": "小刀", "target": target["name"],
"effect": "DAMAGED", "damage": damage, "target_health": target["health"]}
elif item == "手雷":
results = []
for opp in opponents:
opp["health"] = max(0, opp["health"] - 3)
results.append({"status": "ITEM_USED", "player": player["name"], "item": "手雷", "target": opp["name"],
"effect": "DAMAGED", "damage": 3, "target_health": opp["health"]})
return results
elif item == "盾牌":
if player["coins"] >= 3:
player["coins"] -= 3
return {"status": "ITEM_USED", "player": player["name"], "item": "盾牌", "effect": "BOUGHT"}
else:
return {"status": "ITEM_USED", "player": player["name"], "item": "盾牌",
"effect": "INSUFFICIENT_COINS"}
elif item == "剑":
if player["coins"] >= 4:
player["coins"] -= 4
return {"status": "ITEM_USED", "player": player["name"], "item": "剑", "effect": "BOUGHT"}
else:
return {"status": "ITEM_USED", "player": player["name"], "item": "剑",
"effect": "INSUFFICIENT_COINS"}
elif item == "伤害药水":
if player["coins"] >= 5:
player["coins"] -= 5
return {"status": "ITEM_USED", "player": player["name"], "item": "伤害药水", "effect": "BOUGHT"}
else:
return {"status": "ITEM_USED", "player": player["name"], "item": "伤害药水",
"effect": "INSUFFICIENT_COINS"}
elif item == "手铐":
if player["coins"] >= 3:
player["coins"] -= 3
return {"status": "ITEM_USED", "player": player["name"], "item": "手铐", "effect": "BOUGHT"}
else:
return {"status": "ITEM_USED", "player": player["name"], "item": "手铐",
"effect": "INSUFFICIENT_COINS"}
elif item == "机器人":
if player["coins"] >= 6:
player["coins"] -= 6
return {"status": "ITEM_USED", "player": player["name"], "item": "机器人", "effect": "BOUGHT"}
else:
return {"status": "ITEM_USED", "player": player["name"], "item": "机器人",
"effect": "INSUFFICIENT_COINS"}
def get_gold(self, player):
if random.random() < 0.5:
gold = random.randint(1, 3)
player["coins"] += gold
return gold
return 0
def demon_action(self, demon, players):
if self.real_count + self.empty_count == 0:
self.real_count = 10
self.empty_count = 0
target = random.choice([p for p in players if p["health"] > 0])
if random.random() < self.real_count / (self.real_count + self.empty_count):
damage = 1
target["health"] = max(0, target["health"] - damage)
self.real_count -= 1
return {"status": "SHOOT_REAL", "shooter": demon["name"], "target": target["name"], "damage": damage,
"target_health": target["health"]}
else:
self.empty_count -= 1
return {"status": "SHOOT_EMPTY", "shooter": demon["name"]}
def run(self):
while self.player1["health"] > 0 and self.player2["health"] > 0:
self.round_num += 1
for player in [self.player1, self.player2]:
opponent = self.player2 if player is self.player1 else self.player2
gold = self.get_gold(player)
if gold > 0:
logging.info(f"{player['name']} 获得了 {gold} 枚金币")
while True:
action = input(f"{player['name']},请选择操作:1. 射击 2. 使用道具 3. 跳过本轮\n")
if action == '1':
result = self.shoot(player, opponent)
logging.info(result)
break
elif action == '2':
result = self.use_item(player, [opponent])
if isinstance(result, list):
for r in result:
logging.info(r)
else:
logging.info(result)
elif action == '3':
logging.info(f"{player['name']} 跳过了本轮")
break
else:
logging.warning("无效输入,请重新选择")
if self.real_count + self.empty_count == 0:
demon = {"name": "恶魔"}
for _ in range(5):
result = self.demon_action(demon, [self.player1, self.player2])
logging.info(result)
if self.player1["health"] <= 0 or self.player2["health"] <= 0:
break
self.add_random_items(self.player1)
self.add_random_items(self.player2)
if self.player1["health"] <= 0:
logging.info(f"{self.player2['name']} 获胜!")
winner_id = [k for k, v in users.items() if v[0] == self.player2["name"]][0]
users[winner_id][2] += 1
elif self.player2["health"] <= 0:
logging.info(f"{self.player1['name']} 获胜!")
winner_id = [k for k, v in users.items() if v[0] == self.player1["name"]][0]
users[winner_id][2] += 1
save_users()
@app.route('/')
def index():
try:
template_path = os.path.join(app.root_path, 'templates', 'index.html')
if not os.path.exists(template_path):
return jsonify({"status": "ERROR", "message": f"模板文件 {template_path} 不存在"}), 500
return render_template('index.html')
except Exception as e:
logging.error(f"加载模板时出错: {str(e)}")
return jsonify({"status": "ERROR", "message": f"加载模板时出错: {str(e)}"}), 500
@app.route('/login', methods=['POST'])
def login():
try:
data = request.get_json()
user_id = data.get('user_id')
password = data.get('password')
if not user_id or not password:
return jsonify({"status": "ERROR", "message": "用户ID和密码不能为空"}), 400
if user_id not in users:
# 注册新用户
username = f"User_{generate_id()}"
users[user_id] = [username, password, 0, [], []]
save_users()
return jsonify({"status": "REGISTER_SUCCESS", "username": username})
elif password == users[user_id][1]:
# 登录成功
return jsonify({"status": "LOGIN_SUCCESS", "username": users[user_id][0]})
else:
# 密码错误
return jsonify({"status": "PASSWORD_ERROR", "message": "密码错误"}), 401
except Exception as e:
logging.error(f"登录/注册时出错: {str(e)}")
return jsonify({"status": "ERROR", "message": str(e)}), 500
@app.route('/match', methods=['POST'])
def match():
try:
data = request.get_json()
user_id = data.get('user_id')
if not user_id:
return jsonify({"status": "ERROR", "message": "用户ID不能为空"}), 400
waiting_players.append(user_id)
if len(waiting_players) >= 2:
player1_id = waiting_players.pop(0)
player2_id = waiting_players.pop(0)
game = Game(player1_id, player2_id)
threading.Thread(target=game.run).start()
return jsonify({"status": "MATCHED",
"opponent_name": users[player2_id][0] if player1_id == user_id else users[player1_id][0]})
else:
return jsonify({"status": "MATCHING"})
except Exception as e:
logging.error(f"匹配时出错: {str(e)}")
return jsonify({"status": "ERROR", "message": str(e)}), 500
@app.route('/rules', methods=['GET'])
def rules():
try:
return jsonify({"status": "SUCCESS", "rules": introduce_rules()})
except Exception as e:
logging.error(f"获取规则时出错: {str(e)}")
return jsonify({"status": "ERROR", "message": str(e)}), 500
@app.route('/quit', methods=['GET'])
def quit():
global server
if server:
server.shutdown()
return jsonify({"status": "SHUTDOWN_SUCCESS", "message": "游戏已退出"})
else:
return jsonify({"status": "ERROR", "message": "服务器未启动"}), 500
class ServerThread(threading.Thread):
def __init__(self, app):
threading.Thread.__init__(self)
self.server = make_server('0.0.0.0', 50003, app)
global server
server = self.server
self.ctx = app.app_context()
self.ctx.push()
def run(self):
self.server.serve_forever()
def shutdown(self):
self.server.shutdown()
if __name__ == "__main__":
load_users()
server = ServerThread(app)
server.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
server.shutdown()
sys.exit(0)
HTML的链接(我只发一次,丢了别找我:https://www.luogu.com.cn/paste/xtnmgx8s)
全部评论 4
luogu剪贴板是进不去的
6天前 来自 上海
0建议修改
6天前 来自 上海
0我知道
5天前 来自 浙江
0了
5天前 来自 浙江
0
html的最后咋不完整?
1周前 来自 广东
0哦,忘了ACGO有字数限制了
1周前 来自 浙江
06
1周前 来自 广东
0
d
1周前 来自 浙江
0d
1周前 来自 浙江
0
有帮助,赞一个