Add idiom solitaire project
This commit is contained in:
parent
c745693acb
commit
fc848dc333
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.env
|
||||
.venv/
|
||||
__pycache__/
|
||||
.DS_Store
|
||||
392
gomoku_game.py
392
gomoku_game.py
@ -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
1553
idiom_solitaire.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
||||
# DeepSeek API Key
|
||||
# Get your API key from https://platform.deepseek.com/
|
||||
DEEPSEEK_API_KEY=sk-b04b9134730c4375a5789e2e00978ee0
|
||||
@ -1 +0,0 @@
|
||||
3.13
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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.
|
||||
@ -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
3037
my-ai-app/uv.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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"
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user