Add idiom solitaire project

This commit is contained in:
st2411020112 2026-01-09 00:28:26 +08:00
parent c745693acb
commit fc848dc333
35 changed files with 1585 additions and 3469 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.env
.venv/
__pycache__/
.DS_Store

View File

@ -1,392 +0,0 @@
import pygame
import sys
# 初始化pygame
pygame.init()
# 游戏常量设置
SCREEN_SIZE = 600 # 窗口大小
GRID_SIZE = 30 # 每个格子的大小
LINE_WIDTH = 2 # 棋盘线宽度
BOARD_SIZE = 19 # 棋盘大小(19x19)
PIECE_RADIUS = 14 # 棋子半径
PIECE_WIDTH = 2 # 棋子边框宽度
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BG_COLOR = (240, 220, 180) # 棋盘背景色(木纹色)
LINE_COLOR = (100, 100, 100)# 棋盘线颜色
# 计算棋盘起始位置(居中显示)
START_X = (SCREEN_SIZE - (BOARD_SIZE - 1) * GRID_SIZE) // 2
START_Y = (SCREEN_SIZE - (BOARD_SIZE - 1) * GRID_SIZE) // 2
# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_SIZE, SCREEN_SIZE))
pygame.display.set_caption("五子棋")
# 游戏模式0表示双人对战1表示AI对战
game_mode = 1 # 默认AI对战
mode_selected = False # 是否已选择游戏模式
# 初始化棋盘数据0表示空1表示黑子2表示白子
board = [[0 for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
current_player = 1 # 1表示黑方2表示白方
game_over = False
winner = None
# AI评估权重
WEIGHTS = {
'win': 100000, # 获胜
'block_win': 50000, # 阻挡对方获胜
'four': 10000, # 四子连珠
'block_four': 5000, # 阻挡对方四子
'three': 1000, # 三子连珠
'block_three': 500, # 阻挡对方三子
'two': 100, # 二子连珠
'block_two': 50, # 阻挡对方二子
'one': 10, # 一子
'block_one': 5 # 阻挡对方一子
}
def draw_board():
"""绘制棋盘"""
# 填充背景色
screen.fill(BG_COLOR)
# 绘制棋盘网格线
for i in range(BOARD_SIZE):
# 竖线
pygame.draw.line(
screen, LINE_COLOR,
(START_X + i * GRID_SIZE, START_Y),
(START_X + i * GRID_SIZE, START_Y + (BOARD_SIZE - 1) * GRID_SIZE),
LINE_WIDTH
)
# 横线
pygame.draw.line(
screen, LINE_COLOR,
(START_X, START_Y + i * GRID_SIZE),
(START_X + (BOARD_SIZE - 1) * GRID_SIZE, START_Y + i * GRID_SIZE),
LINE_WIDTH
)
# 绘制棋子
for row in range(BOARD_SIZE):
for col in range(BOARD_SIZE):
if board[row][col] != 0:
center_x = START_X + col * GRID_SIZE
center_y = START_Y + row * GRID_SIZE
color = BLACK if board[row][col] == 1 else WHITE
# 绘制棋子
pygame.draw.circle(screen, color, (center_x, center_y), PIECE_RADIUS)
# 绘制棋子边框(增加视觉效果)
pygame.draw.circle(screen, BLACK, (center_x, center_y), PIECE_RADIUS, PIECE_WIDTH)
def get_click_pos(pos):
"""将鼠标点击位置转换为棋盘坐标"""
x, y = pos
# 计算所在格子
col = (x - START_X + GRID_SIZE // 2) // GRID_SIZE
row = (y - START_Y + GRID_SIZE // 2) // GRID_SIZE
# 检查是否在棋盘范围内
if 0 <= row < BOARD_SIZE and 0 <= col < BOARD_SIZE:
return (row, col)
return None
def check_win(row, col):
"""检查落子后是否获胜"""
player = board[row][col]
directions = [
(0, 1), # 横向
(1, 0), # 纵向
(1, 1), # 正对角线
(1, -1) # 反对角线
]
for dr, dc in directions:
count = 1
# 正方向检查
r, c = row + dr, col + dc
while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and board[r][c] == player:
count += 1
r += dr
c += dc
# 反方向检查
r, c = row - dr, col - dc
while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and board[r][c] == player:
count += 1
r -= dr
c -= dc
# 五子连珠则获胜
if count >= 5:
return True
return False
def evaluate_position(row, col, player):
"""评估指定位置对玩家的价值"""
if board[row][col] != 0:
return -1000000 # 已经有棋子的位置
score = 0
opponent = 1 if player == 2 else 2
# 模拟落子
board[row][col] = player
# 检查是否获胜
if check_win(row, col):
score += WEIGHTS['win']
# 评估各个方向的连珠情况
directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
for dr, dc in directions:
# 检查当前玩家的连珠
count = 1
# 正方向
r, c = row + dr, col + dc
while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and board[r][c] == player:
count += 1
r += dr
c += dc
# 反方向
r, c = row - dr, col - dc
while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and board[r][c] == player:
count += 1
r -= dr
c -= dc
# 根据连珠数量加分
if count == 4:
score += WEIGHTS['four']
elif count == 3:
score += WEIGHTS['three']
elif count == 2:
score += WEIGHTS['two']
elif count == 1:
score += WEIGHTS['one']
# 撤销模拟落子
board[row][col] = 0
# 模拟对方落子,检查需要阻挡的情况
board[row][col] = opponent
if check_win(row, col):
score += WEIGHTS['block_win']
for dr, dc in directions:
# 检查对方的连珠
count = 1
# 正方向
r, c = row + dr, col + dc
while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and board[r][c] == opponent:
count += 1
r += dr
c += dc
# 反方向
r, c = row - dr, col - dc
while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and board[r][c] == opponent:
count += 1
r -= dr
c -= dc
# 根据连珠数量加分(阻挡)
if count == 4:
score += WEIGHTS['block_four']
elif count == 3:
score += WEIGHTS['block_three']
elif count == 2:
score += WEIGHTS['block_two']
elif count == 1:
score += WEIGHTS['block_one']
# 撤销模拟落子
board[row][col] = 0
# 中心位置加成
center_row, center_col = BOARD_SIZE // 2, BOARD_SIZE // 2
distance = abs(row - center_row) + abs(col - center_col)
score += (10 - distance) * 2
return score
def ai_move():
"""AI落子"""
best_score = -float('inf')
best_move = None
# 遍历棋盘上的所有空位
for row in range(BOARD_SIZE):
for col in range(BOARD_SIZE):
if board[row][col] == 0:
# 评估该位置的价值
score = evaluate_position(row, col, current_player)
if score > best_score:
best_score = score
best_move = (row, col)
# 执行最佳落子
if best_move:
row, col = best_move
board[row][col] = current_player
return (row, col)
return None
def show_winner():
"""显示获胜信息"""
# 尝试使用系统中文字体
try:
font = pygame.font.SysFont(["SimHei", "Microsoft YaHei", "Arial"], 60)
except:
font = pygame.font.Font(None, 60)
text = f"{'黑方' if winner == 1 else '白方'}获胜!"
text_surface = font.render(text, True, (255, 0, 0))
text_rect = text_surface.get_rect(center=(SCREEN_SIZE//2, SCREEN_SIZE//2))
screen.blit(text_surface, text_rect)
# 显示重新开始提示
try:
font_small = pygame.font.SysFont(["SimHei", "Microsoft YaHei", "Arial"], 30)
except:
font_small = pygame.font.Font(None, 30)
restart_text = "按R键重新开始 | 按Q键退出"
restart_surface = font_small.render(restart_text, True, BLACK)
restart_rect = restart_surface.get_rect(center=(SCREEN_SIZE//2, SCREEN_SIZE//2 + 50))
screen.blit(restart_surface, restart_rect)
def show_mode_selection():
"""显示游戏模式选择界面"""
# 填充背景色
screen.fill(BG_COLOR)
# 显示标题
try:
title_font = pygame.font.SysFont(["SimHei", "Microsoft YaHei", "Arial"], 48)
except:
title_font = pygame.font.Font(None, 48)
title_text = "五子棋"
title_surface = title_font.render(title_text, True, BLACK)
title_rect = title_surface.get_rect(center=(SCREEN_SIZE//2, SCREEN_SIZE//2 - 100))
screen.blit(title_surface, title_rect)
# 显示模式选择
try:
font = pygame.font.SysFont(["SimHei", "Microsoft YaHei", "Arial"], 36)
except:
font = pygame.font.Font(None, 36)
# 双人对战选项
pvp_text = "1. 双人对战"
pvp_surface = font.render(pvp_text, True, BLACK)
pvp_rect = pvp_surface.get_rect(center=(SCREEN_SIZE//2, SCREEN_SIZE//2))
screen.blit(pvp_surface, pvp_rect)
# AI对战选项
ai_text = "2. AI对战"
ai_surface = font.render(ai_text, True, BLACK)
ai_rect = ai_surface.get_rect(center=(SCREEN_SIZE//2, SCREEN_SIZE//2 + 60))
screen.blit(ai_surface, ai_rect)
# 显示操作提示
try:
hint_font = pygame.font.SysFont(["SimHei", "Microsoft YaHei", "Arial"], 24)
except:
hint_font = pygame.font.Font(None, 24)
hint_text = "请按数字键选择游戏模式"
hint_surface = hint_font.render(hint_text, True, BLACK)
hint_rect = hint_surface.get_rect(center=(SCREEN_SIZE//2, SCREEN_SIZE//2 + 120))
screen.blit(hint_surface, hint_rect)
pygame.display.update()
def restart_game():
"""重新开始游戏"""
global board, current_player, game_over, winner, mode_selected
board = [[0 for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
current_player = 1
game_over = False
winner = None
mode_selected = False # 重新开始时需要重新选择模式
def main():
"""游戏主循环"""
global current_player, game_over, winner, game_mode, mode_selected
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 键盘事件处理
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r: # 按R重新开始
restart_game()
if event.key == pygame.K_q: # 按Q退出
pygame.quit()
sys.exit()
# 游戏模式选择
if not mode_selected:
if event.key == pygame.K_1:
game_mode = 0 # 双人对战
mode_selected = True
elif event.key == pygame.K_2:
game_mode = 1 # AI对战
mode_selected = True
# 鼠标点击落子(游戏未结束且已选择模式时)
if event.type == pygame.MOUSEBUTTONDOWN and not game_over and mode_selected:
pos = pygame.mouse.get_pos()
board_pos = get_click_pos(pos)
if board_pos:
row, col = board_pos
# 检查位置是否为空
if board[row][col] == 0:
board[row][col] = current_player
# 检查是否获胜
if check_win(row, col):
game_over = True
winner = current_player
else:
# 切换玩家
current_player = 2 if current_player == 1 else 1
# 如果是AI对战模式且当前玩家是AI白方则AI落子
if game_mode == 1 and current_player == 2:
ai_pos = ai_move()
if ai_pos:
ai_row, ai_col = ai_pos
# 检查AI落子后是否获胜
if check_win(ai_row, ai_col):
game_over = True
winner = current_player
else:
# 切换回玩家
current_player = 1
# 如果未选择模式,显示模式选择界面
if not mode_selected:
show_mode_selection()
else:
# 绘制游戏界面
draw_board()
# 如果游戏结束,显示获胜信息
if game_over:
show_winner()
# 更新屏幕显示
pygame.display.update()
clock.tick(60)
if __name__ == "__main__":
main()

1553
idiom_solitaire.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
# DeepSeek API Key
# Get your API key from https://platform.deepseek.com/
DEEPSEEK_API_KEY=sk-b04b9134730c4375a5789e2e00978ee0

View File

@ -1 +0,0 @@
3.13

View File

Binary file not shown.

View File

@ -1,14 +0,0 @@
# Welcome to Chainlit! 🚀🤖
Hi there, Developer! 👋 We're excited to have you on board. Chainlit is a powerful tool designed to help you prototype, debug and share applications built on top of LLMs.
## Useful Links 🔗
- **Documentation:** Get started with our comprehensive [Chainlit Documentation](https://docs.chainlit.io) 📚
- **Discord Community:** Join our friendly [Chainlit Discord](https://discord.gg/k73SQ3FyUh) to ask questions, share your projects, and connect with other developers! 💬
We can't wait to see what you create with Chainlit! Happy coding! 💻😊
## Welcome screen
To modify the welcome screen, edit the `chainlit.md` file at the root of your project. If you do not want a welcome screen, just leave this file empty.

View File

@ -1,14 +0,0 @@
[project]
name = "my-ai-app"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"openai>=2.14.0",
"python-dotenv>=1.2.1",
"streamlit>=1.30.0",
"chainlit>=0.1.160",
"fastapi>=0.128.0",
"uvicorn>=0.40.0",
]

3037
my-ai-app/uv.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,32 @@
[project]
name = "my-ai-app"
version = "0.1.0"
description = "Add your description here"
description = "AI-powered Gomoku game with web interface"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"openai>=2.14.0",
"python-dotenv>=1.2.1",
"streamlit>=1.30.0",
"chainlit>=0.1.160",
]
requires-python = ">=3.12" # 2026 Recommended
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[tool.uv]
environments = ["default"]
[tool.uv.environment.default]
python = ">=3.12"
[tool.uv.dependencies]
flask = "^3.0.0"
python-dotenv = "^1.2.1"
requests = "^2.32.0"
streamlit = "^1.30.0"
chainlit = "^0.1.160"
pygame = "^2.6.0"
pydantic = "^2.0.0"
pydantic-settings = "^2.0.0"
[tool.uv.dependencies.dev]
pytest = "^7.0.0"
black = "^23.0.0"
isort = "^5.0.0"