Compare commits
5 Commits
main
...
guess-numb
| Author | SHA1 | Date |
|---|---|---|
|
|
ad4c593584 | 4 months ago |
|
|
e9f7bbef84 | 4 months ago |
|
|
d28aec75e9 | 4 months ago |
|
|
e092223993 | 4 months ago |
|
|
813c1d0066 | 4 months ago |
@ -0,0 +1,19 @@
|
||||
import requests, json, time
|
||||
URL = 'http://127.0.0.1:5000/api'
|
||||
|
||||
def log(r): print(json.dumps(r, ensure_ascii=False, indent=2))
|
||||
|
||||
# 1. 开局
|
||||
target = requests.post(URL+'/start', json={'range': 100}).json()['target']
|
||||
print('目标:', target)
|
||||
|
||||
# 2. 猜 3 次
|
||||
for g in [50, 25, 37]:
|
||||
res = requests.post(URL+'/guess', json={'guess': g}).json()
|
||||
log(res)
|
||||
if res['result'] == 'equal':
|
||||
print('🎉 猜中!等级:', res['rank'])
|
||||
break
|
||||
|
||||
# 3. 最佳
|
||||
log(requests.get(URL+'/best').json())
|
||||
@ -0,0 +1,136 @@
|
||||
from flask import Flask, request, jsonify
|
||||
from flask_cors import CORS
|
||||
import random, json, os, time
|
||||
from datetime import datetime
|
||||
|
||||
app = Flask(__name__)
|
||||
CORS(app) # 允许跨域
|
||||
|
||||
DATA_DIR = 'data'
|
||||
BEST_FILE = os.path.join(DATA_DIR, 'best.json')
|
||||
CACHE_FILE = os.path.join(DATA_DIR, 'cache.json')
|
||||
|
||||
# ---------------- 工具 ----------------
|
||||
def _load_json(path, default):
|
||||
os.makedirs(DATA_DIR, exist_ok=True)
|
||||
if not os.path.exists(path):
|
||||
json.dump(default, open(path, 'w', encoding='utf-8'))
|
||||
return json.load(open(path, 'r', encoding='utf-8'))
|
||||
|
||||
def _save_json(path, obj):
|
||||
json.dump(obj, open(path, 'w', encoding='utf-8'), ensure_ascii=False)
|
||||
|
||||
# ---------------- 等级 ----------------
|
||||
def rank(times: int) -> str:
|
||||
if times <= 5: return '大神'
|
||||
if times <= 8: return '优秀'
|
||||
if times <= 12: return '合格'
|
||||
return '再接再厉'
|
||||
|
||||
# ---------------- 提示 ----------------
|
||||
def hint(target: int, history: list) -> dict:
|
||||
"""每 3 次未中给 1 条线索"""
|
||||
h_len = len(history)
|
||||
if h_len == 0 or h_len % 3 != 0:
|
||||
return {'unlock': False}
|
||||
return {
|
||||
'unlock': True,
|
||||
'odd_even': '奇数' if target % 2 else '偶数',
|
||||
'range': f'{max(1, target-10)}-{min(100, target+10)}'
|
||||
}
|
||||
|
||||
# ================= API =================
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return 'Guess-Number-Backend OK'
|
||||
|
||||
# 1. 选题人:生成 / 自定义目标数
|
||||
@app.route('/api/start', methods=['POST'])
|
||||
def start():
|
||||
"""
|
||||
前端发:{"range":100} 或 {"custom":42}
|
||||
返回:{"target": 42}
|
||||
同时清空本局缓存
|
||||
"""
|
||||
data = request.get_json(force=True)
|
||||
if 'custom' in data:
|
||||
target = int(data['custom'])
|
||||
else:
|
||||
r = int(data.get('range', 100))
|
||||
target = random.randint(1, r)
|
||||
# 缓存本局
|
||||
_save_json(CACHE_FILE, {'target': target, 'history': []})
|
||||
return jsonify(target=target)
|
||||
|
||||
# 2. 猜数人:提交猜测
|
||||
@app.route('/api/guess', methods=['POST'])
|
||||
def guess():
|
||||
"""
|
||||
发:{"guess": 50}
|
||||
返回:
|
||||
{
|
||||
"result": "big|small|equal",
|
||||
"times": 3,
|
||||
"rank": "优秀",
|
||||
"hint": {"unlock":true, "odd_even":"奇数", "range":"40-60"}
|
||||
}
|
||||
"""
|
||||
body = request.get_json(force=True)
|
||||
guess_num = int(body['guess'])
|
||||
|
||||
cache = _load_json(CACHE_FILE, {'target': 0, 'history': []})
|
||||
target = cache['target']
|
||||
history = cache['history']
|
||||
|
||||
if target == 0:
|
||||
return jsonify(error='本局未开始,请先调用 /api/start'), 400
|
||||
|
||||
history.append(guess_num)
|
||||
times = len(history)
|
||||
result = ('equal' if guess_num == target else
|
||||
'big' if guess_num > target else 'small')
|
||||
|
||||
resp = {'result': result, 'times': times, 'rank': rank(times)}
|
||||
|
||||
# 更新最佳
|
||||
if result == 'equal':
|
||||
best = _load_json(BEST_FILE, {'count': 999, 'date': ''})
|
||||
if times < best['count']:
|
||||
best = {'count': times, 'date': datetime.now().strftime('%Y-%m-%d')}
|
||||
_save_json(BEST_FILE, best)
|
||||
|
||||
# 提示
|
||||
resp['hint'] = hint(target, history)
|
||||
|
||||
# 写回缓存
|
||||
_save_json(CACHE_FILE, cache)
|
||||
return jsonify(resp)
|
||||
|
||||
# 3. 获取提示(前端可点按钮触发)
|
||||
@app.route('/api/hint', methods=['GET'])
|
||||
def get_hint():
|
||||
cache = _load_json(CACHE_FILE, {'target': 0, 'history': []})
|
||||
if cache['target'] == 0:
|
||||
return jsonify(error='本局未开始'), 400
|
||||
return jsonify(hint(cache['target'], cache['history']))
|
||||
|
||||
# 4. 历史最佳
|
||||
@app.route('/api/best', methods=['GET'])
|
||||
def best():
|
||||
return jsonify(_load_json(BEST_FILE, {'count': 999, 'date': ''}))
|
||||
|
||||
# 5. 本局缓存(刷新页面时前端可恢复)
|
||||
@app.route('/api/cache', methods=['GET'])
|
||||
def cache():
|
||||
return jsonify(_load_json(CACHE_FILE, {'target': 0, 'history': []}))
|
||||
|
||||
# 6. 重新开始(清缓存)
|
||||
@app.route('/api/reset', methods=['POST'])
|
||||
def reset():
|
||||
_save_json(CACHE_FILE, {'target': 0, 'history': []})
|
||||
return jsonify(ok=True)
|
||||
|
||||
# ================= 启动 =================
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
||||
@ -0,0 +1,45 @@
|
||||
import random
|
||||
from datetime import datetime
|
||||
|
||||
class GameCore:
|
||||
"""游戏核心逻辑类,封装目标数生成、提示生成、等级判断等功能"""
|
||||
|
||||
@staticmethod
|
||||
def generate_target(min_num: int, max_num: int, custom_num: int = None) -> int:
|
||||
"""生成目标数(支持随机生成或自定义输入)"""
|
||||
if min_num >= max_num:
|
||||
raise ValueError("最小值必须小于最大值")
|
||||
if custom_num is not None:
|
||||
if min_num <= custom_num <= max_num:
|
||||
return custom_num
|
||||
else:
|
||||
raise ValueError(f"自定义数必须在 {min_num}-{max_num} 范围内")
|
||||
return random.randint(min_num, max_num)
|
||||
|
||||
@staticmethod
|
||||
def get_level(guess_count: int) -> str:
|
||||
"""根据猜数次数返回等级评价"""
|
||||
if guess_count <= 5:
|
||||
return "大神"
|
||||
elif 6 <= guess_count <= 8:
|
||||
return "优秀"
|
||||
elif 9 <= guess_count <= 12:
|
||||
return "合格"
|
||||
else:
|
||||
return "再接再厉"
|
||||
|
||||
@staticmethod
|
||||
def generate_hint(target_num: int, history_guesses: list, min_num: int, max_num: int) -> str:
|
||||
"""生成提示(优先区间范围,再返回奇偶性)"""
|
||||
# 从历史猜数中筛选有效区间(小于目标数的最大值、大于目标数的最小值)
|
||||
lower = [g for g in history_guesses if g < target_num]
|
||||
upper = [g for g in history_guesses if g > target_num]
|
||||
|
||||
min_hint = max(lower) if lower else min_num
|
||||
max_hint = min(upper) if upper else max_num
|
||||
|
||||
# 优先返回区间提示(如果有有效范围)
|
||||
if min_hint > min_num or max_hint < max_num:
|
||||
return f"目标数在 {min_hint + 1} - {max_hint - 1} 之间"
|
||||
# 否则返回奇偶性提示
|
||||
return f"目标数是{'奇数' if target_num % 2 != 0 else '偶数'}"
|
||||
Loading…
Reference in new issue