ai自制原创棋
ai自制原创棋
·
请注意以下棋类完全由本人原创构思+ai代码构成,简单梳理可玩性后推出【规则封装至程序】
瘸子棋.py
import numpy as np import os import sys from enum import Enum class GameState(Enum): MENU = 1 PLAYING = 2 RULES = 3 GAME_OVER = 4 class LameChessGame: def __init__(self, n=17): if n % 2 == 0: n += 1 # 确保棋盘有中心点 self.n = n self.board = np.full((n, n), ' ', dtype=str) # 初始化棋盘 self.center = n // 2 self.pawn_pos = (self.center, self.center) # 瘸子初始位置 self.board[self.center][self.center] = 'P' # 放置瘸子 # 设置终点位置 self.goal_A = (self.center, 0) self.goal_B = (self.center, n - 1) self.board[self.goal_A] = 'G' # A终点标记 self.board[self.goal_B] = 'G' # B终点标记 self.current_player = 'A' # A先手 self.valves = {'A': [], 'B': []} # 存储转向阀位置 self.turn_positions = [] # 记录转动路径 self.move_count = 0 self.winner = None self.game_state = GameState.MENU self.valid_placements = [] # 存储当前可放置位置 self.preview_dict = {} # 预览位置字典(位置->数字编号) self.consecutive_no_moves = 0 # 连续无移动回合计数 def clear_screen(self): """清屏函数""" os.system('cls' if os.name == 'nt' else 'clear') def print_header(self): """打印游戏标题""" print("=" * 60) print(f"{'瘸 子 棋 游 戏':^60}") print("=" * 60) print(f"{'棋盘大小: ' + str(self.n) + 'x' + str(self.n):^60}") print("=" * 60) def print_board(self, preview_dict=None): """打印当前棋盘状态""" if preview_dict is None: preview_dict = {} # 列坐标 col_header = " " + " ".join(f"{i:02d}" for i in range(self.n)) print(col_header) print(" ┌" + "──" * self.n + "─┐") for r in range(self.n): row_str = f"{r:02d} │ " for c in range(self.n): pos = (r, c) cell = self.board[r][c] # 显示预览位置数字 display_char = None if pos in preview_dict: num = preview_dict[pos] display_char = f'\033[1;37;44m{num}\033[0m' # 蓝底白字加粗 if display_char: row_str += display_char elif cell == 'G' and pos == self.goal_A: # A终点 row_str += '\033[91m★\033[0m' elif cell == 'G' and pos == self.goal_B: # B终点 row_str += '\033[94m★\033[0m' elif cell == 'P': # 瘸子 row_str += '\033[92m♞\033[0m' elif cell == 'A': # A阀门 row_str += '\033[91m■\033[0m' elif cell == 'B': # B阀门 row_str += '\033[94m■\033[0m' elif cell == ' ': # 空位 row_str += '·' else: # 其他 row_str += f'{cell}' row_str += ' ' # 格子间空格 row_str += "│" print(row_str) print(" └" + "──" * self.n + "─┘") print( f"玩家 \033[91mA\033[0m 目标: ({self.goal_A[0]}, {self.goal_A[1]}) | 玩家 \033[94mB\033[0m 目标: ({self.goal_B[0]}, {self.goal_B[1]})") print(f"当前回合: 玩家 \033[{'91' if self.current_player == 'A' else '94'}m{self.current_player}\033[0m") print(f"移动次数: {self.move_count}") def get_adjacent_positions(self, pos): """获取相邻位置""" r, c = pos positions = [] for dr, dc in [(0, 1), (1, 0), (0, -1), (-1, 0)]: nr, nc = r + dr, c + dc if 0 <= nr < self.n and 0 <= nc < self.n: positions.append((nr, nc)) return positions def place_valve(self): """放置转向阀阶段(强制放置)""" self.clear_screen() self.print_header() adjacent = self.get_adjacent_positions(self.pawn_pos) self.valid_placements = [pos for pos in adjacent if self.board[pos] == ' ' or self.board[pos] == 'G'] self.preview_dict = {} # 重置预览字典 # 如果没有可放置位置,直接跳过 if not self.valid_placements: print("\n\033[33m无可放置位置,跳过放置阶段\033[0m") input("按Enter继续...") return False # 创建位置-数字映射 for i, pos in enumerate(self.valid_placements): if i < 9: # 只显示1-9 self.preview_dict[pos] = i + 1 # 打印棋盘并显示预览位置数字 self.print_board(preview_dict=self.preview_dict) print(f"\n\033[92m请选择放置位置:\033[0m") for i, pos in enumerate(self.valid_placements): # 为每个选项显示数字编号 num_display = f"[\033[44m{i+1}\033[0m]" if i < 9 else f"[{i+1}]" print(f"{num_display}: ({pos[0]}, {pos[1]})") while True: try: choice = input("请输入放置位置编号: ") choice = int(choice) if 1 <= choice <= len(self.valid_placements): pos = self.valid_placements[choice - 1] r, c = pos # 放置转向阀 self.board[r][c] = self.current_player self.valves[self.current_player].append((r, c)) print( f"玩家 \033[{'91' if self.current_player == 'A' else '94'}m{self.current_player}\033[0m 在 ({r},{c}) 放置了转向阀") return True else: print("\033[33m编号无效,请重新选择\033[0m") except: print("\033[33m输入无效,请重新选择\033[0m") def is_valve_in_straight_line(self, valve_pos): """检查阀门是否在瘸子的同一行或同一列(水平或垂直方向)""" r1, c1 = self.pawn_pos r2, c2 = valve_pos return r1 == r2 or c1 == c2 def check_path_to_valve(self, valve_pos): """检查到阀门的路径是否畅通(只检查水平和垂直方向)""" r1, c1 = self.pawn_pos r2, c2 = valve_pos # 首先检查是否在水平或垂直方向 if not self.is_valve_in_straight_line(valve_pos): return False # 确定方向向量 dr = r2 - r1 dc = c2 - c1 # 标准化方向 step_r = 0 if dr == 0 else 1 if dr > 0 else -1 step_c = 0 if dc == 0 else 1 if dc > 0 else -1 # 计算步数 steps = max(abs(dr), abs(dc)) # 检查路径上的每个格子(不包括起点和终点) for i in range(1, steps): r = r1 + i * step_r c = c1 + i * step_c cell = self.board[r][c] # 只允许空格、终点或当前玩家的阀门 if cell == ' ' or cell == 'G' or cell == self.current_player: continue else: return False return True def calculate_rotation(self, valve_pos): """计算旋转后的位置""" pr, pc = self.pawn_pos vr, vc = valve_pos # 计算相对向量 dr, dc = pr - vr, pc - vc # 计算旋转后的位置 (90度) clockwise = (vr - dc, vc + dr) # 顺时针 counter_clockwise = (vr + dc, vc - dr) # 逆时针 valid_positions = [] for direction, pos in [('顺时针', clockwise), ('逆时针', counter_clockwise)]: r, c = pos # 检查位置是否在棋盘内 if not (0 <= r < self.n and 0 <= c < self.n): continue # 检查落点是否为空或终点(仅允许移动到自己的终点) cell = self.board[r][c] if cell == ' ': pass # 空位总是允许 elif cell == 'G': # 终点位置 # 玩家A只能移动到A终点,玩家B只能移动到B终点 if (self.current_player == 'A' and (r, c) != self.goal_A) or \ (self.current_player == 'B' and (r, c) != self.goal_B): continue # 跳过对方终点 else: continue # 其他情况不允许 # 检查路径是否畅通 if not self.check_path_to_valve(valve_pos): continue # 避免回到原点 if len(self.turn_positions) > 1 and pos == self.turn_positions[-2]: continue valid_positions.append((direction, pos)) return valid_positions def rotate_pawn(self): """转动瘸子阶段""" self.turn_positions = [self.pawn_pos] valve_usage = {} # 本回合阀门使用计数(每回合重置) moved = False # 标记本回合是否进行了移动 while True: self.clear_screen() self.print_header() available_rotations = [] self.preview_dict = {} # 重置预览字典 # 检查所有可用的转向阀(只考虑水平和垂直方向) for valve_pos in self.valves[self.current_player]: # 首先检查阀门是否在水平和垂直方向 if not self.is_valve_in_straight_line(valve_pos): continue # 检查使用次数(本回合内) if valve_usage.get(valve_pos, 0) < 3: rotations = self.calculate_rotation(valve_pos) for direction, pos in rotations: available_rotations.append((valve_pos, direction, pos)) # 创建预览位置字典 for idx, (_, _, pos) in enumerate(available_rotations, start=1): if idx <= 9: # 只显示1-9 self.preview_dict[pos] = idx # 打印棋盘并显示预览位置数字 self.print_board(preview_dict=self.preview_dict) if not available_rotations: if not moved: # 如果整个回合都没移动过 print("\n\033[33m无可用的转动操作\033[0m") else: print("\n\033[33m无法继续转动\033[0m") input("按Enter结束转动阶段...") return moved # 显示可用操作 print("\n\033[92m可用转动操作:\033[0m") for i, (valve, direction, pos) in enumerate(available_rotations): # 为每个选项使用不同颜色 direction_color = '\033[96m' if direction == '顺时针' else '\033[95m' # 如果位置有预览数字,显示在操作中 preview_num = self.preview_dict.get(pos, ' ') preview_display = f"[\033[44m{preview_num}\033[0m]" if pos in self.preview_dict else "[ ]" print( f"{preview_display} {i + 1}: 使用阀({valve[0]},{valve[1]}) {direction_color}{direction}\033[0m → 移动到({pos[0]},{pos[1]})") print("\033[48;5;196m 0 \033[0m: 结束转动阶段") # 玩家选择 try: choice = input("请选择操作编号: ") if choice == '0': break choice = int(choice) if 1 <= choice <= len(available_rotations): valve_pos, direction, new_pos = available_rotations[choice - 1] # 更新使用次数 valve_usage[valve_pos] = valve_usage.get(valve_pos, 0) + 1 # 移动瘸子 old_r, old_c = self.pawn_pos new_r, new_c = new_pos self.board[old_r][old_c] = ' ' self.board[new_r][new_c] = 'P' self.pawn_pos = (new_r, new_c) self.turn_positions.append(new_pos) moved = True # 标记已移动 self.move_count += 1 direction_color = '\033[96m' if direction == '顺时针' else '\033[95m' print( f"\n玩家 \033[{'91' if self.current_player == 'A' else '94'}m{self.current_player}\033[0m 使用阀{valve_pos} {direction_color}{direction}\033[0m 移动到 ({new_r},{new_c})") # 检查胜利条件 if (self.current_player == 'A' and new_pos == self.goal_A) or \ (self.current_player == 'B' and new_pos == self.goal_B): self.winner = self.current_player return True else: print("\033[33m编号无效,请重新选择\033[0m") except: print("\033[33m输入无效,请重新选择\033[0m") return moved def play_turn(self): """执行一个完整回合""" # 放置阶段(强制放置) placed = self.place_valve() # 转动阶段 moved = self.rotate_pawn() # 如果本回合有移动操作,重置无移动计数 if placed or moved: self.consecutive_no_moves = 0 else: self.consecutive_no_moves += 1 print(f"\n\033[33m玩家 {self.current_player} 本回合无有效操作\033[0m") print(f"连续无操作回合: {self.consecutive_no_moves}/2") input("按Enter继续...") # 检查胜利条件 if self.winner: return True # 切换玩家 self.current_player = 'B' if self.current_player == 'A' else 'A' return False def show_rules(self): """显示游戏规则(更新版)""" self.clear_screen() self.print_header() print("\n\033[93m游戏规则:\033[0m") print("1. 在一个n×n的棋盘上,A和B轮流博弈") print("2. 棋盘中心有一个♞棋子(瘸子)") print("3. 每回合玩家必须:") print(" a. 在瘸子相邻的4个方向放置一个转向阀(■)(如有位置)") print(" b. 使用自己的转向阀进行90度旋转移动(如有可能)") print("4. 关键限制:") print(" - 只能使用与瘸子在同一行或同一列(水平或垂直方向)的阀门") print(" - 不能使用对角线方向上的阀门") print("5. 旋转规则:") print(" - 路径上不能有对方阀门") print(" - 落点必须是空位(·)或己方终点(★)") print(" - 同一阀门一回合最多使用3次") print("6. 阀门使用:") print(" - 阀门永久有效,可跨回合使用") print("7. 胜利条件:") print(" - 玩家A将♞移动到左侧终点★(中心行,第0列)") print(" - 玩家B将♞移动到右侧终点★(中心行,最后一列)") print("8. 平局条件:") print(" - 双方连续两回合无法进行任何移动") print("\n\033[93m操作说明:\033[0m") print("- 放置阶段:棋盘上蓝色数字显示的位置是可选放置位置") print("- 放置阶段:选择对应数字编号放置阀门") print("- 转动阶段:棋盘上蓝色数字显示的位置是可选目标位置") print("- 转动阶段:选择对应数字编号进行转动") print("- 转动选项显示方向:\033[96m顺时针\033[0m 或 \033[95m逆时针\033[0m") print("\n按Enter返回主菜单...") input() def show_menu(self): """显示主菜单""" self.clear_screen() self.print_header() print("\n\033[93m主菜单:\033[0m") print("\033[48;5;40m 1 \033[0m 开始新游戏") print("\033[48;5;45m 2 \033[0m 游戏规则") print("\033[48;5;196m 3 \033[0m 退出游戏") while True: choice = input("\n请选择: ") if choice == '1': self.__init__(self.n) # 重置游戏 self.game_state = GameState.PLAYING return elif choice == '2': self.game_state = GameState.RULES return elif choice == '3': sys.exit(0) else: print("\033[33m无效选择,请重新输入\033[0m") def show_game_over(self): """显示游戏结束画面""" self.clear_screen() self.print_header() self.print_board() if self.winner == 'DRAW': print("\n╔════════════════════════╗") print("║ \033[93m平 局!\033[0m ║") print("╚════════════════════════╝") print("双方连续两回合无法进行任何移动") else: color = '\033[91m' if self.winner == 'A' else '\033[94m' print(f"\n╔════════════════════════╗") print(f"║ 玩家 {color}{self.winner}\033[0m \033[93m获胜!\033[0m ║") print("╚════════════════════════╝") print("\n\033[93m选择:\033[0m") print("\033[48;5;40m 1 \033[0m 返回主菜单") print("\033[48;5;196m 2 \033[0m 退出游戏") while True: choice = input("\n请选择: ") if choice == '1': self.game_state = GameState.MENU return elif choice == '2': sys.exit(0) else: print("\033[33m无效选择,请重新输入\033[0m") def play_game(self): """主游戏循环""" self.consecutive_no_moves = 0 while True: if self.game_state == GameState.MENU: self.show_menu() elif self.game_state == GameState.RULES: self.show_rules() self.game_state = GameState.MENU elif self.game_state == GameState.PLAYING: game_ended = self.play_turn() if self.winner: self.game_state = GameState.GAME_OVER continue # 检查平局条件 if self.consecutive_no_moves >= 2: self.winner = 'DRAW' self.game_state = GameState.GAME_OVER elif self.game_state == GameState.GAME_OVER: self.show_game_over() # 启动游戏 if __name__ == "__main__": # 检查终端尺寸 if os.name == 'nt': # Windows os.system('mode con: cols=80 lines=50') game = LameChessGame(17) # 17x17棋盘 game.play_game()
推推棋.py
import numpy as np import random import time import os class PushGame: def __init__(self, rows=7, cols=5): # 修改为7行5列 self.set_board_size(rows, cols) self.reset_game() def set_board_size(self, rows, cols): """设置棋盘大小并计算相关参数""" self.rows = rows self.cols = cols self.center = (rows // 2, cols // 2) # 7//2=3, 5//2=2 -> (3,2) self.win_count = 1 # 获胜所需中心点计数 def reset_game(self): """重置游戏状态""" # 创建空棋盘 self.board = np.full((self.rows, self.cols), '.', dtype='U1') # 初始化中心点计数 self.center_counts = [0, 0] # [A的中心点计数, B的中心点计数] # 初始化玩家位置 - 底边和顶边全放棋子 # A (玩家0) 在底部一行(所有列) for j in range(self.cols): self.board[-1, j] = 'A' # B (玩家1) 在顶部一行(所有列) for j in range(self.cols): self.board[0, j] = 'B' self.current_player = 0 # 0=A, 1=B self.last_positions = [] # 存储最近的位置用于检测僵局 self.game_history = [] # 存储完整游戏历史 self.move_count = 0 # 移动计数器 self.last_push_info = None # 记录上一步的推动信息 def get_state_key(self): """生成唯一状态标识""" return hash(str(self.board) + str(self.current_player) + str(self.center_counts)) def is_valid_position(self, x, y): """检查坐标是否有效""" return 0 <= x < self.rows and 0 <= y < self.cols def get_adjacent_pieces(self, x, y): """获取相邻位置的棋子信息""" directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 右, 下, 左, 上 adjacent = [] for dx, dy in directions: nx, ny = x + dx, y + dy if self.is_valid_position(nx, ny): piece = self.board[nx, ny] if piece != '.': # 忽略空位 adjacent.append(((nx, ny), piece, (dx, dy))) return adjacent def can_push_special(self, x, y, direction): """检查特殊推动是否可行""" dx, dy = direction player_char = 'A' if self.current_player == 0 else 'B' # 检查推动方向上的相邻位置 ax, ay = x + dx, y + dy if not self.is_valid_position(ax, ay) or self.board[ax, ay] == '.': return False # 检查特殊规则条件 adjacent_piece = self.board[ax, ay] if dx == 0: # 水平推动 if adjacent_piece != player_char: # 必须是自己棋子 return False else: # 垂直推动 if adjacent_piece == player_char: # 必须是对手棋子 return False # 检查目标位置是否为空 tx, ty = ax + dx, ay + dy return self.is_valid_position(tx, ty) and self.board[tx, ty] == '.' def can_push_normal(self, x, y, direction): """检查普通推动是否可行""" dx, dy = direction cx, cy = x, y # 检查第一步是否有效 nx, ny = cx + dx, cy + dy if not self.is_valid_position(nx, ny) or self.board[nx, ny] != '.': return False return True def push_piece(self, x, y, direction, move_type): """执行推动操作""" dx, dy = direction player_char = 'A' if self.current_player == 0 else 'B' if move_type == 'special': # 特殊推动:移动两个棋子 ax, ay = x + dx, y + dy tx, ty = ax + dx, ay + dy # 移动相邻棋子 self.board[tx, ty] = self.board[ax, ay] self.board[ax, ay] = '.' # 移动主棋子 self.board[x + dx, y + dy] = self.board[x, y] self.board[x, y] = '.' elif move_type == 'normal': # 普通推动:推动直到遇到障碍 cx, cy = x, y while True: nx, ny = cx + dx, cy + dy if not self.is_valid_position(nx, ny) or self.board[nx, ny] != '.': break cx, cy = nx, ny # 移动棋子到最终位置 self.board[cx, cy] = self.board[x, y] self.board[x, y] = '.' def find_winner(self): """检查胜利条件""" if self.center_counts[0] >= self.win_count: return 0 # A获胜 elif self.center_counts[1] >= self.win_count: return 1 # B获胜 return -1 # 无胜者 def is_draw(self): """检查是否平局""" # 检查僵局条件(连续3次重复局面) if len(self.last_positions) >= 6: if (self.last_positions[-1] == self.last_positions[-3] == self.last_positions[-5] and self.last_positions[-2] == self.last_positions[-4] == self.last_positions[-6]): return True # 检查是否无合法移动 if not self.get_valid_moves(): self.current_player = 1 - self.current_player if not self.get_valid_moves(): return True self.current_player = 1 - self.current_player return False def get_valid_moves(self): """获取所有合法移动""" valid_moves = [] player_char = 'A' if self.current_player == 0 else 'B' directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 右, 下, 左, 上 # 查找所有可能的移动 for x in range(self.rows): for y in range(self.cols): if self.board[x, y] == player_char: # 检查特殊推动 for direction in directions: if self.can_push_special(x, y, direction): valid_moves.append((x, y, direction, 'special')) # 检查普通推动 for direction in directions: if self.can_push_normal(x, y, direction): valid_moves.append((x, y, direction, 'normal')) # 禁止反推规则 if self.last_push_info is not None: if self.current_player != self.last_push_info['from_player']: pushed_pos = self.last_push_info['pushed_piece_final_pos'] pushed_dir = self.last_push_info['pushed_direction'] reverse_dir = (-pushed_dir[0], -pushed_dir[1]) filtered_moves = [] for move in valid_moves: x, y, dir, mtype = move if mtype == 'special' and (x, y) == pushed_pos and dir == reverse_dir: continue filtered_moves.append(move) valid_moves = filtered_moves return valid_moves def make_move(self, move=None): """执行移动""" if move is None: valid_moves = self.get_valid_moves() if not valid_moves: return False move = random.choice(valid_moves) x, y, direction, move_type = move self.push_piece(x, y, direction, move_type) # 检查是否有棋子到达中心点 cx, cy = self.center if self.board[cx, cy] != '.': if self.board[cx, cy] == 'A': self.center_counts[0] += 1 elif self.board[cx, cy] == 'B': self.center_counts[1] += 1 self.board[cx, cy] = '.' # 记录上一步的推动信息(垂直特殊推动) self.last_push_info = None if move_type == 'special' and direction[0] != 0: pushed_piece_final_pos = (x + 2 * direction[0], y + 2 * direction[1]) self.last_push_info = { 'pushed_piece_final_pos': pushed_piece_final_pos, 'pushed_direction': direction, 'from_player': self.current_player } # 记录游戏状态 self.last_positions.append(self.get_state_key()) self.game_history.append(( self.current_player, (x, y), direction, move_type, np.copy(self.board), self.center_counts.copy() )) # 检查游戏结束条件 winner = self.find_winner() if winner != -1: return winner if self.is_draw(): return 2 # 平局 # 切换到下一个玩家 self.current_player = 1 - self.current_player self.move_count += 1 return None def simulate_game(self, max_moves=1000): """模拟完整游戏""" self.reset_game() result = None for _ in range(max_moves): result = self.make_move() if result is not None: break if result is None: return 2 # 平局 return result def visualize_board(self, piece_colors=None): """可视化棋盘""" reset_color = '\033[0m' center_color = '\033[93m' # 中心点颜色 (黄色) default_color = reset_color player_char = 'A' if self.current_player == 0 else 'B' # 显示中心点计数 print(f"中心点计数: A={self.center_counts[0]}/{self.win_count}, B={self.center_counts[1]}/{self.win_count}") # 显示棋盘 for i, row in enumerate(self.board): for j, cell in enumerate(row): if cell == 'A' or cell == 'B': if piece_colors and (i, j) in piece_colors: color_code = piece_colors[(i, j)] elif piece_colors is None: color_code = '\033[91m' if cell == 'A' else '\033[94m' elif cell == player_char: color_code = '\033[91m' if self.current_player == 0 else '\033[94m' else: color_code = '\033[90m' # 对手颜色 print(f"{color_code}●{reset_color}", end=" ") elif (i, j) == self.center: print(f"{center_color}★{reset_color}", end=" ") else: print("·", end=" ") print() player_colors = { 0: '\033[91mA\033[0m', 1: '\033[94mB\033[0m' } def show_rules(): """显示简化后的游戏规则""" os.system('cls' if os.name == 'nt' else 'clear') print("推推棋游戏规则") print("=" * 40) print("1. 目标:先将1个棋子送入中心点(★)者获胜") print() print("2. 棋盘布局:") print(f" - 7行×5列棋盘,底部行是A方(红●),顶部行是B方(蓝●)") # 修改尺寸说明 print(" - 中心位置标记为★") print() print("3. 移动方式:") print(" ① 普通推动:向相邻空位推自己的棋,会一直移动到遇障碍为止") print(" ② 特殊推动:") print(" - 水平推(左/右):只能推相邻的自己的棋,被推棋前进一格") print(" - 垂直推(上/下):只能推相邻的对手的棋,被推棋前进一格") print() print("4. 特殊规则:") print(" - 棋子进入中心点后会被移除,同时增加对应玩家计数") print(" - 被垂直推动的棋子,下一回合不能被反方向推回") print(" - 连续3次重复局面或双方无合法移动均判为平局") print("=" * 40) # 显示初始棋盘 print("\n初始棋盘状态:") game = PushGame() game.visualize_board() input("\n按任意键返回主菜单...") def interactive_game(): """交互式游戏""" game = PushGame() direction_symbols = { (0, 1): '→', (1, 0): '↓', (0, -1): '←', (-1, 0): '↑' } # 不同棋子的颜色集合 piece_colors = [ '\033[91m', '\033[92m', '\033[93m', '\033[94m', '\033[95m', '\033[96m', '\033[97m', '\033[31m', '\033[32m', '\033[33m' ] reset_color = '\033[0m' print(f"欢迎来到推推棋游戏! 棋盘大小: {game.rows}行×{game.cols}列") print("操作说明:") print("- 输入移动编号选择要执行的操作") print("- 输入 'exit' 可随时退出游戏") print("- 移动类型:普通(→↓←↑)、特殊(会标注)") # 显示初始棋盘 print(f"\n{game.rows}行×{game.cols}列棋盘初始状态:") game.visualize_board() input("\n按回车键开始游戏...") while True: # 外层循环用于多局游戏 game = PushGame() exit_flag = False while True: # 内层循环用于单局游戏 # 清屏并显示棋盘 os.system('cls' if os.name == 'nt' else 'clear') # 显示当前棋盘信息 print(f"棋盘大小: {game.rows}行×{game.cols}列 | 获胜所需中心点: {game.win_count}") # 获取所有合法移动 valid_moves = game.get_valid_moves() # 创建棋子颜色映射字典 color_map = {} if valid_moves: piece_positions = set((x, y) for x, y, _, _ in valid_moves) sorted_pieces = sorted(piece_positions, key=lambda pos: (pos[0], pos[1])) # 为每个可移动棋子分配颜色 for i, pos in enumerate(sorted_pieces): color_index = i % len(piece_colors) color_map[pos] = piece_colors[color_index] # 显示棋盘 game.visualize_board(piece_colors=color_map) if not valid_moves: print("无合法移动! 游戏结束") break # 按棋子分组移动选项 moves_by_piece = {} for move in valid_moves: x, y, direction, move_type = move piece_key = (x, y) if piece_key not in moves_by_piece: moves_by_piece[piece_key] = [] moves_by_piece[piece_key].append((direction, move_type)) # 显示合法移动 print("\n可移动选项:") move_counter = 1 move_map = {} color_index = 0 # 按位置排序棋子 sorted_pieces = sorted(moves_by_piece.keys(), key=lambda pos: (pos[0], pos[1])) for piece in sorted_pieces: x, y = piece color_code = piece_colors[color_index % len(piece_colors)] color_index += 1 # 打印棋子标题 print(f"{color_code}棋子 {color_index}{reset_color} 的移动:") # 获取并排序该棋子的移动选项 directions = moves_by_piece[piece] sorted_directions = sorted(directions, key=lambda d: d[0]) # 打印移动选项 for direction, move_type in sorted_directions: dir_symbol = direction_symbols[direction] move_type_str = "特殊" if move_type == 'special' else "普通" move_map[move_counter] = (x, y, direction, move_type) print(f" {color_code}{move_counter}. {dir_symbol} {move_type_str}{reset_color}") move_counter += 1 print() # 添加空行分隔 # 获取玩家输入 player_char = 'A' if game.current_player == 0 else 'B' player_color = '\033[91m' if game.current_player == 0 else '\033[94m' user_input = input( f"\n{player_color}玩家 {player_char}{reset_color} 的回合 (输入编号): ").strip().lower() if user_input == 'exit': exit_flag = True break # 处理输入 if user_input.isdigit(): move_index = int(user_input) if move_index in move_map: move = move_map[move_index] else: print(f"无效编号: {move_index}!") time.sleep(1) continue else: print("请输入有效编号!") time.sleep(1) continue # 执行移动 result = game.make_move(move) if result == 0: os.system('cls' if os.name == 'nt' else 'clear') game.visualize_board() print("\033[91m玩家 A 获胜!\033[0m") break elif result == 1: os.system('cls' if os.name == 'nt' else 'clear') game.visualize_board() print("\033[94m玩家 B 获胜!\033[0m") break elif result == 2: os.system('cls' if os.name == 'nt' else 'clear') game.visualize_board() print("平局!") break if exit_flag: break # 完全退出游戏 # 询问是否再来一局 replay = input("\n再来一局? (y/n): ").strip().lower() if replay != 'y': break if __name__ == "__main__": while True: os.system('cls' if os.name == 'nt' else 'clear') print("推推棋游戏") print("1. 开始游戏") print("2. 游戏规则") print("3. 退出") choice = input("\n请选择 (1-3): ").strip() if choice == '1': interactive_game() elif choice == '2': show_rules() elif choice == '3': print("退出程序") break else: print("无效选择,请重新输入") time.sleep(1)
更多推荐
所有评论(0)