1 Star 0 Fork 3

StarEuler/DLC

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
sgfview.py 4.41 KB
一键复制 编辑 原始数据 按行查看 历史
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)
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/StarEuler/DLC.git
git@gitee.com:StarEuler/DLC.git
StarEuler
DLC
DLC
master

搜索帮助