代码拉取完成,页面将自动刷新
同步操作将从 阿晏/deep-learning and chess 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
import curses
import sys
import re
# 定义列标签
columns = "ABCDEFGHJKLMNOPQRST" # 围棋棋盘的列标签
def parse_sgf(sgf_content):
# 逐行读取SGF文件内容
lines = sgf_content.strip().split(';')
moves = []
# 跳过第一行(通常是棋谱的元数据),解析后续的棋步
for line in lines[1:]:
if line.startswith('B[') or line.startswith('W['):
# 提取棋步坐标
match = re.search(r"[A-T][1-9][0-9]?", line[2:])
if not match:
print(f"Warning: Invalid move format: {line}")
continue
moves.append(match.group(0))
return moves
def coord_to_board(coord):
# 将SGF坐标转换为棋盘上的行和列索引
# SGF中,A=0, B=1, ..., T=18
try:
col = columns.index(coord[0].upper())
row = int(coord[1:]) - 1 # 行号从1到19,SGF也是从1到19
return row, col
except (ValueError, IndexError):
print(f"Warning: Invalid coordinate: {coord}")
return None, None
def draw_board(stdscr, board, current_move, total_moves, current_color, current_move_info):
# 清除屏幕
stdscr.clear()
# 打印列标
col_labels = " " + " ".join(columns)
stdscr.addstr(0, 0, col_labels)
for row in range(19):
# 行号从上到下,i=0 对应棋盘的第1行
screen_row = row + 1
# 打印行号
stdscr.addstr(screen_row, 0, f"{row + 1:2d} ")
# 打印棋盘内容
row_str = " ".join(board[row])
stdscr.addstr(screen_row, 3, row_str)
# 打印右侧行号
stdscr.addstr(screen_row, 4 + 2*19, f" {row + 1}")
# 打印底部列标
stdscr.addstr(20, 0, col_labels)
# 打印当前步数、总步数、当前棋子颜色和当前棋谱
status_line = (
f"Use arrows to navigate, 'q' to quit. | "
f"Move {current_move + 1}/{total_moves} | "
f"{current_color} | "
f"{current_move_info}"
)
stdscr.addstr(21, 0, status_line)
# 刷新屏幕
stdscr.refresh()
def main(stdscr, sgf_file):
curses.curs_set(0) # 隐藏光标
# 读取SGF文件
with open(sgf_file, "r") as file:
sgf_content = file.read()
# 解析棋步
moves = parse_sgf(sgf_content)
total_moves = len(moves)
# 创建一个空白棋盘
board = [['+' for _ in range(19)] for _ in range(19)]
current_move = 0
update_board(board, moves, current_move)
current_color = 'B' if current_move % 2 == 0 else 'W'
current_move_info = moves[current_move] if current_move < total_moves else ""
draw_board(stdscr, board, current_move, total_moves, current_color, current_move_info)
while True:
key = stdscr.getch()
if key == curses.KEY_RIGHT: # 下一步
if current_move < total_moves - 1:
current_move += 1
elif key == curses.KEY_LEFT: # 上一步
if current_move > 0:
current_move -= 1
elif key == curses.KEY_HOME: # 第一步
current_move = 0
elif key == curses.KEY_END: # 最后一步
current_move = total_moves - 1
elif key == curses.KEY_PPAGE: # 上10步
current_move = max(0, current_move - 10)
elif key == curses.KEY_NPAGE: # 下10步
current_move = min(total_moves - 1, current_move + 10)
elif key == ord('q'): # 退出
break
# 更新棋盘
update_board(board, moves, current_move)
current_color = 'B' if current_move % 2 == 0 else 'W'
current_move_info = moves[current_move] if current_move < total_moves else ""
draw_board(stdscr, board, current_move, total_moves, current_color, current_move_info)
def update_board(board, moves, current_move):
# 清空棋盘
for row in range(19):
for col in range(19):
board[row][col] = '+'
for i, move in enumerate(moves[:current_move + 1]):
row, col = coord_to_board(move)
if row is None or col is None:
continue
if i % 2 == 0: # 黑子
board[row][col] = '●'
else: # 白子
board[row][col] = '○'
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python script.py <sgf_file>")
sys.exit(1)
sgf_file = sys.argv[1]
curses.wrapper(main, sgf_file)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。