boxmoe_header_banner_img

Hello! 欢迎来到悠悠畅享网!

文章导读

Python战舰游戏开发教程:构建核心游戏循环与智能命中检测


avatar
作者 2025年8月29日 10

Python战舰游戏开发教程:构建核心游戏循环与智能命中检测

本教程详细指导如何在python中构建一个功能完善的战舰游戏。我们将从基础的游戏板创建和船只放置开始,逐步深入探讨如何实现回合制游戏循环、玩家与电脑的交互、智能的命中检测逻辑,以及如何利用“虚拟”敌方战场提升用户体验,最终实现完整的游戏胜利判断。

1. 游戏基础结构与初始化

构建战舰游戏首先需要定义游戏的基本元素和初始化流程。这包括欢迎玩家、创建游戏地图、以及玩家和电脑船只的初始部署。

1.1 用户欢迎与地图创建

游戏开始时,首先获取玩家昵称并显示欢迎信息。游戏地图通过二维列表表示,初始状态下所有格子均为空(_)。

from random import randrange  # 船只类型定义 ship_initial = ["B", "C", "F", "A", "S"] ship_names = ["Battleship", "Cruiser", "Frigate", "aircraft Carrier", "Sub"] map_size = 10 # 地图大小  def get_username():     """获取玩家昵称"""     while True:         user_name = input("请输入您的名字: ")         if user_name:             print(f"欢迎来到战舰游戏, {user_name}!")             return user_name         else:             print("请勿输入空值。")  def create_battlefield(size):     """根据指定大小创建游戏地图"""     return [["_"] * size for _ in range(size)]  def display_battlefield(board):     """显示当前地图状态"""     for row in board:         print(" ".join(row))

1.2 玩家与电脑船只部署

玩家手动输入坐标放置船只,电脑则随机放置。为避免船只重叠,玩家放置时需检查坐标是否已被占用;电脑放置时则需确保目标格子为空。

def player_ship_coordinate(player_board, occupied_coords):     """     玩家手动放置船只。     参数:         player_board: 玩家自己的地图。         occupied_coords: 一个集合,存储已被占用的坐标,防止船只重叠。     """     print("请放置您的船只:")     for i, ship_name in enumerate(ship_names):         while True:             try:                 row = int(input(f"请输入 {ship_name} 的行坐标 (0-9): "))                 col = int(input(f"请输入 {ship_name} 的列坐标 (0-9): "))                 if 0 <= row < map_size and 0 <= col < map_size and (row, col) not in occupied_coords:                     player_board[row][col] = ship_initial[i]                     occupied_coords.add((row, col))                     break                 else:                     print("无效坐标或该位置已被占用。请重新输入。")             except ValueError:                 print("输入无效。请输入一个整数。")     return player_board, occupied_coords  def comp_ship_coordinate(comp_board):     """     电脑随机放置船只。     参数:         comp_board: 电脑的地图。     """     for ship_char in ship_initial:         while True:             row = randrange(0, map_size)             col = randrange(0, map_size)             if comp_board[row][col] == "_":                 comp_board[row][col] = ship_char                 break     return comp_board

2. 实现回合制游戏循环

游戏的核心是回合制循环,玩家和电脑轮流攻击,直到一方所有船只被击沉。

2.1 游戏主循环结构

在 if __name__ == “__main__”: 块中,我们初始化游戏并进入一个无限循环,直到有玩家获胜。player_hits 和 comp_hits 变量用于跟踪双方击沉的船只数量。

立即学习Python免费学习笔记(深入)”;

if __name__ == "__main__":     user = get_username()      player_board = create_battlefield(map_size)     comp_board = create_battlefield(map_size)     dummy_board = create_battlefield(map_size) # 玩家视角的电脑地图,初始为空      occupied_coords = set()      print("n玩家部署船只:")     player_ship_coordinate(player_board, occupied_coords)     print("n您的战场:")     display_battlefield(player_board)      print("n电脑部署船只:")     comp_ship_coordinate(comp_board)     # display_battlefield(comp_board) # 测试时可以显示电脑地图,实际游戏中应隐藏     print("n电脑的战场 (您的攻击目标):")     display_battlefield(dummy_board) # 玩家只能看到虚拟地图      player_hits = 0 # 玩家击中电脑船只的数量     comp_hits = 0   # 电脑击中玩家船只的数量      while True:         print(f"n--- {user} 的回合 ---")         # 玩家攻击         hit_status = check_player_hit(comp_board, dummy_board, user)         player_hits += hit_status         print("n电脑的战场 (您的攻击结果):")         display_battlefield(dummy_board)          if player_hits == len(ship_initial): # 如果玩家击沉所有船只             print(f"n恭喜 {user},您击沉了所有敌舰,赢得游戏!")             break          print("n--- 电脑的回合 ---")         # 电脑攻击         hit_status = check_comp_hit(player_board)         comp_hits += hit_status         print("n您的战场 (电脑的攻击结果):")         display_battlefield(player_board)          if comp_hits == len(ship_initial): # 如果电脑击沉所有船只             print("n很遗憾,电脑击沉了您的所有船只,电脑赢得游戏!")             break

3. 玩家射击与“虚拟”敌方战场

为了提供更好的游戏体验,玩家不应直接看到电脑的船只部署。我们引入一个“虚拟战场”(dummy_board),它只显示玩家的攻击结果(命中或未命中)。

3.1 check_player_hit 函数

这个函数负责处理玩家的攻击。它接收电脑的真实地图 (comp_board) 和玩家视角的虚拟地图 (dummy_board)。

  • 玩家输入攻击坐标。
  • 根据 comp_board 判断是否命中。
  • 如果命中,dummy_board 对应位置标记为 ‘X’,comp_board 上的船只标记为小写字母(表示已击中)。
  • 如果未命中,dummy_board 对应位置标记为 ‘*’。
  • 函数返回 1 表示命中,0 表示未命中。
def check_player_hit(comp_board, dummy_board, user_name):     """     玩家攻击敌方船只。     参数:         comp_board: 电脑的真实地图。         dummy_board: 玩家可见的虚拟地图。         user_name: 玩家昵称,用于提示信息。     返回: 1 表示命中,0 表示未命中。     """     while True:         try:             print(f"{user_name},请选择您的攻击坐标。")             row = int(input("请输入攻击的行坐标 (0-9): "))             col = int(input("请输入攻击的列坐标 (0-9): "))             if 0 <= row < map_size and 0 <= col < map_size:                 # 检查是否重复攻击同一位置                 if dummy_board[row][col] != '_' :                     print("您已经攻击过这个位置了。请选择其他坐标。")                     continue                 break             else:                 print("无效坐标。请重新输入 (0-9)。")         except ValueError:             print("输入无效。请输入一个整数。")      hit = 0 # 默认未命中      target_char = comp_board[row][col]     if target_char in ship_initial: # 命中船只         comp_board[row][col] = target_char.lower() # 标记为已击中(小写)         dummy_board[row][col] = "X" # 虚拟地图显示命中         print(f"命中!电脑的 {ship_names[ship_initial.index(target_char)]} 被击中了!")         hit = 1     else: # 未命中         dummy_board[row][col] = "*" # 虚拟地图显示未命中         print("未命中!")     return hit

4. 电脑AI射击逻辑

电脑的攻击需要一定的智能性,至少要避免重复攻击已命中或已尝试过的位置。

4.1 check_comp_hit 函数

这个函数处理电脑的攻击。

  • 电脑随机选择一个坐标,但会确保该坐标之前未被攻击过(即不是 ‘*’ 或已击中的小写船只字符)。
  • 根据 player_board 判断是否命中。
  • 如果命中,player_board 上的船只标记为小写字母。
  • 如果未命中,player_board 对应位置标记为 ‘*’。
  • 函数返回 1 表示命中,0 表示未命中。
def check_comp_hit(player_board):     """     电脑攻击玩家船只。     参数:         player_board: 玩家的真实地图。     返回: 1 表示命中,0 表示未命中。     """     hit = 0 # 默认未命中      while True: # 随机选择一个未曾攻击过的位置         row = randrange(0, map_size)         col = randrange(0, map_size)         # 确保电脑不会重复攻击已经命中或尝试过的位置         if player_board[row][col] not in ["*", "a", "b", "c", "f", "s"]:             break      print(f"电脑选择了坐标 ({row}, {col}) 进行攻击。")      target_char = player_board[row][col]     if target_char in ship_initial: # 命中船只         player_board[row][col] = target_char.lower() # 标记为已击中(小写)         print(f"您的 {ship_names[ship_initial.index(target_char)]} 被击中了!")         hit = 1     else: # 未命中         player_board[row][col] = "*" # 标记为未命中         print("电脑未命中!")     return hit

5. 游戏胜利条件判断

游戏胜利的条件是当一方击沉了对方所有船只。在本教程中,我们假设每艘船只占据一个格子,共有5艘船。因此,当 player_hits 或 comp_hits 达到5时,游戏结束。

在主游戏循环中,每次攻击后都会检查胜利条件:

        # ... (玩家攻击代码) ...         player_hits += hit_status         # ... (显示玩家视角电脑地图) ...          if player_hits == len(ship_initial): # 如果玩家击沉所有船只             print(f"n恭喜 {user},您击沉了所有敌舰,赢得游戏!")             break          # ... (电脑攻击代码) ...         comp_hits += hit_status         # ... (显示玩家地图) ...          if comp_hits == len(ship_initial): # 如果电脑击沉所有船只             print("n很遗憾,电脑击沉了您的所有船只,电脑赢得游戏!")             break

6. 注意事项与代码优化建议

  • 错误处理增强: 当前代码已包含基本的 try-except 进行输入验证,但可以进一步细化,例如对玩家输入坐标的范围进行更严格的检查,并提供更友好的提示。
  • 船只大小与方向: 现有实现中所有船只都只占据一个格子。要实现更真实的战舰游戏,需要扩展船只类,使其具有长度和方向(水平或垂直),并在放置船只时进行碰撞检测和边界检查。
  • 游戏状态管理: 可以引入一个更复杂的船只对象来管理每艘船的状态(如生命值、是否被击沉),而不是仅仅通过地图上的字符变化来判断。
  • 更智能的电脑AI: 当前电脑AI只是随机攻击未曾攻击过的位置。更高级的AI可以在击中船只后,优先攻击相邻的格子,以“追踪”并击沉船只。
  • 用户界面: 对于命令行游戏,可以考虑使用ANSI转义序列来为输出添加颜色,提升可读性。如果希望更复杂的界面,可以考虑使用pygame等图形库。
  • 模块化: 随着游戏复杂度的增加,可以将不同的功能(如船只管理、玩家操作、电脑AI)拆分到不同的模块或类中,提高代码的可维护性。例如,可以创建 Ship 类、Player 类和 Computer 类。
  • 代码可读性 确保变量命名清晰,函数功能单一,并添加足够的注释。

总结

通过本教程,我们构建了一个Python战舰游戏的基础框架,涵盖了从游戏初始化、船只部署到回合制战斗循环和胜利条件判断的核心逻辑。关键改进包括引入“虚拟战场”以隐藏电脑船只位置,以及优化电脑AI使其避免重复攻击。这个基础版本为进一步扩展和提升游戏体验奠定了坚实的基础,例如实现多格船、更复杂的AI策略以及图形用户界面等。



评论(已关闭)

评论已关闭

text=ZqhQzanResources