数组初学者向导:使用Python从零开始制作经典战舰游戏

2023-09-19 16:20:39

引言

战舰游戏,一个广受欢迎的经典游戏,为玩家提供了策略与猜测的完美结合。这个游戏的核心思想是通过猜测敌方船只的位置并尝试击沉它们来赢得比赛。在这篇文章中,我们将使用Python语言和数组来构建这款游戏,让你更加了解数组的操作和实用性。

1. 游戏概述

在战舰游戏中,每位玩家都有一个10 x 10的网格,可以放置5艘船只。这些船只有不同的长度,并且可以横向或纵向放置。玩家和计算机轮流猜测对方网格上的坐标,并尝试“攻击”。如果某个坐标上有船,那么这个坐标就被标记为“被击中”。如果某艘船的所有坐标都被击中,那么这艘船就被认为是“被击沉”。当一个玩家的所有船只都被击沉时,游戏结束。

2. 游戏设置

我们首先需要为玩家和计算机设置10 x 10的游戏网格。在Python中,我们可以使用列表的列表(即数组)来实现这个网格。

def create_board():
    """创建一个10x10的游戏网格"""
    return [["O"] * 10 for _ in range(10)]

这里,每个"O"代表一个空的网格位置。我们会在后续过程中更新这些位置来显示船只或攻击的结果。

3. 船只的放置

我们需要为玩家和电脑放置船只。为简单起见,我们假设每艘船的长度为3。这意味着每艘船都需要3个连续的网格位置。

import random

def place_ships(board, num_ships=5, ship_length=3):
    """在指定的游戏板上放置船只"""
    for _ in range(num_ships):
        while True:
            direction = random.choice(["horizontal", "vertical"])
            if direction == "horizontal":
                row = random.randint(0, 9)
                col = random.randint(0, 10 - ship_length)
            else:  # vertical
                row = random.randint(0, 10 - ship_length)
                col = random.randint(0, 9)

            # 检查该位置是否可用
            if direction == "horizontal":
                if all([board[row][col + i] == "O" for i in range(ship_length)]):
                    for i in range(ship_length):
                        board[row][col + i] = "S"
                    break
            else:
                if all([board[row + i][col] == "O" for i in range(ship_length)]):
                    for i in range(ship_length):
                        board[row + i][col] = "S"
                    break

在这里,我们首先随机选择放置船只的方向(横向或纵向)。然后,我们随机选择一个起始坐标,并检查这个坐标及其连续位置是否都为空。如果都为空,我们就在这些位置放置船只。

注意:为了简洁和清晰,本文中的代码可能不是最优的或最完整的实现。为了获得完整的项目和更多的优化技巧,请下载完整项目

4. 游戏循环与攻击

在游戏开始之前,玩家和电脑都已经部署了他们的船只。现在,我们需要设置一个游戏循环,其中玩家和电脑轮流进行攻击。

首先,我们定义一个函数来让玩家输入他想要攻击的坐标:

def player_attack():
    """让玩家选择攻击的坐标"""
    while True:
        try:
            row, col = map(int, input("请输入你要攻击的坐标(例如: 5,3): ").split(','))
            if 0 <= row < 10 and 0 <= col < 10:
                return row, col
            print("坐标必须在0-9之间。")
        except ValueError:
            print("请输入有效的坐标,例如: 5,3。")

接下来,我们定义一个函数让电脑随机选择一个攻击坐标:

def computer_attack():
    """电脑随机选择攻击坐标"""
    return random.randint(0, 9), random.randint(0, 9)

现在,我们可以定义一个函数来执行实际的攻击:

def attack(board, row, col):
    """在指定的坐标上执行攻击"""
    if board[row][col] == "S":
        board[row][col] = "H"  # Hit
        return "H"
    elif board[row][col] == "O":
        board[row][col] = "M"  # Miss
        return "M"
    else:
        return None  # 已经攻击过的位置

最后,我们需要一个游戏循环来处理玩家和电脑的轮流攻击:

def game_loop(player_board, computer_board):
    """主游戏循环"""
    while True:
        # 玩家攻击
        row, col = player_attack()
        result = attack(computer_board, row, col)
        if result == "H":
            print("命中!")
            if all(cell == "M" or cell == "H" for row in computer_board for cell in row):
                return "Player Wins"
        elif result == "M":
            print("失误!")
        else:
            print("你已经攻击过这个位置了!")

        # 电脑攻击
        row, col = computer_attack()
        result = attack(player_board, row, col)
        if result == "H":
            print(f"电脑命中了坐标 {row},{col}!")
            if all(cell == "M" or cell == "H" for row in player_board for cell in row):
                return "Computer Wins"
        elif result == "M":
            print(f"电脑在坐标 {row},{col} 失误!")

5. 游戏结果展示

游戏结束时,我们需要告诉玩家谁赢得了比赛。

def display_result(winner):
    """展示游戏结果"""
    if winner == "Player Wins":
        print("恭喜你击败了电脑!")
    else:
        print("电脑赢得了比赛!")

6. 辅助功能:展示游戏板

为了让玩家知道他们的游戏进度和船只的状态,我们需要一个函数来展示游戏板。

def display_board(board):
    """展示指定的游戏板"""
    for row in board:
        print(" ".join(row))
    print("\n" + "-" * 20 + "\n")

这个函数会打印游戏板上的每一行,使其看起来更加整齐。

7. 启动游戏

现在,我们需要一个启动游戏的函数,将之前定义的所有函数组合起来:

def start_game():
    """开始战舰游戏"""
    # 创建游戏板
    player_board = create_board()
    computer_board = create_board()

    # 放置船只
    place_ships(player_board)
    place_ships(computer_board)

    # 游戏主循环
    winner = game_loop(player_board, computer_board)

    # 展示结果
    display_result(winner)

    # 展示完整的电脑游戏板,以便玩家知道船只的位置
    print("电脑的游戏板:")
    display_board(computer_board)

8. 总结

通过本教程,我们使用Python和数组构建了一个简单的战舰游戏。在这个过程中,我们学习了如何创建和操作数组,如何随机放置船只,如何管理游戏循环,以及如何展示结果。

这款游戏可以进一步完善和扩展。例如,你可以增加不同长度的船只,为电脑玩家添加更复杂的策略,或者增加更丰富的用户界面。

我们鼓励你使用这篇文章作为起点,探索更多的功能和创新,从而进一步提高你的编程和问题解决能力。

9. 扩展思路

  1. 增加不同类型的船只:船只可以有不同的大小,如航空母舰(5个单位长度)、战列舰(4个单位长度)等。
  2. 增加障碍物:在游戏板上添加障碍物,增加游戏的策略性和复杂性。
  3. 更智能的电脑玩家:你可以为电脑玩家设计更复杂的策略,比如基于前几次攻击的结果进行猜测等。
  4. 图形用户界面:使用Python的图形库,如Tkinter或Pygame,为游戏添加一个图形用户界面。

这就是我们的完整战舰游戏教程!希望这篇文章能帮助你更加熟悉数组的概念,并鼓励你进一步探索编程的乐趣。

注意:为了简洁和清晰,本文中的代码可能不是最优的或最完整的实现。为了获得完整的项目和更多的优化技巧,请下载完整项目

更多推荐

Go基础语法:基本数据类型

3基本数据类型基本数据类型包括:整型、浮点型、布尔型、字符串。除以上基本类型之外,还有数组、切片、结构体、函数、map、通道等。3.1整型3.1.1整型整型分为:int8、int16、int32、int64,以及对应的无符号整型:uint8、uint16、uint32、uint64其中unit8对应其他语言中的byte

数据结构——图(图的存储及基本操作)

文章目录前言一、邻接矩阵法(顺序存储)1.无向图存储邻接矩阵算法2.有向图存储邻接矩阵算法二、邻接表法(图的链式存储结构)总结前言邻接矩阵法(图的顺序存储结构)1.1无向图邻接矩阵算法1.2有向图邻接矩阵算法邻接表法(图的一种链式存储结构)一、邻接矩阵法(顺序存储)定义:用一个一维数组存储顶点,一个二维数组存储边的信息

Mac专用投屏工具AirServer 7 .27 for Mac中文免费激活版

AirServer7.27forMac中文免费激活版是一款Mac专用投屏工具,能够通过本地网络将音频、照片、视频以及支持AirPlay功能的第三方App,从iOS设备无线传送到Mac电脑的屏幕上,把Mac变成一个AirPlay终端的实用工具。目前最新的AirServer7.2.7版本,支持macOSHighSierra

goaccess 日志分析 nginx

分析命令:goaccess-a-d-f/mnt/winshare/access-2023070112.log-pgoaccess.conf-o/mydata/nginx/html/2023070112_new.html分析日志时的参数goaccess使用参数详解-a开启UserAgent列表。开启后会降低解析速度-c在

高成本获客时代,企业如何通过营销自动化实现突围?

在数字化时代,随着市场竞争的不断升级,企业在获客方面面临了前所未有的挑战。不论是B端或C端的市场和运营部门纷纷寻求可降低获客成本的新运营路径,将有限的预算花在刀刃上。企业迫切需要寻求更加智能和高效的方式来吸引、转化和留住潜在客户,而营销自动化正是解决这些问题的利器。今天运营坛将和大家探讨获客和培育这两大核心。一、高成本

用低代码开发工具高效构建企业门户

企业信息门户EIP是指将各种应用系统、数据资源和互联网资源统一集中,根据每个用户使用特点和角色的不同,形成个性化的应用界面,并通过对事件和消息的处理、传输把用户有机地联系在一起。企业随着业务的发展,运作的复杂度也在不断加大,再加上各部门的业务量和业务的复杂度都在不断增加,可能已经建设了ERP、OA、考勤、合同、BPM、

阿里测开面试大全(一)附答案完整版

万字长文,建议收藏1什么是POM,为什么要使用它?POM是PageObjectModel的简称,它是一种设计思想,而不是框架。大概的意思是,把一个一个页面,当做一个对象,页面的元素和元素之间操作方法就是页面对象的属性和行为,所以自然而然就用了类的思想来组织我们的页面。一般一个页面写一个类文件,这个类文件包含该页面的元素

【Git】Git 变基(rebase)以及rebase和merge之间的区别

Git变基1.变基—rebase在Git中整合来自不同分支的修改主要有两种方法:merge以及rebase。在前面的文章中已经介绍了merge,这里我们来学习另一个指令rebase。变基的基本操作回顾之前在分支的合并中的一个例子,在该例子中,我们可以看到开发任务分叉到两个不同分支,又各自提交了更新。之前介绍过,整合分支

行为树的基本概念和C++库

一说明行为树是计算机科学、机器人技术、控制系统和视频游戏中使用的计划执行的数学模型。它们以模块化方式描述一组有限任务之间的切换。他们的优势来自于他们能够创建由简单任务组成的非常复杂的任务,而不用担心简单任务是如何实现的。行为树与分层状​​态机有一些相似之处关键区别在于行为的主要构建块是任务而不是状态。它易于人类理解,使

服务器中了勒索病毒怎么办?勒索病毒解密,数据恢复

勒索病毒是一种比较常见的电脑病毒,它们给企业的生产经营和发展带来了很大的影响。可是绝大多数企业在这方面并没有做合理的预案,这也导致当安全运维人员或者企业主发现中了勒索病毒以后手足无措。那云天数据恢复中心就用这篇文章来告诉大家当服务器中了勒索病毒怎么办。一,隔离受感染的电脑或者系统为了生产经营方便,很多用户的服务器或者电

七夕特别篇 | 浪漫的Bug

文章目录前言一、迷失的爱情漩涡(多线程中的错误同步)1.1Bug背景1.2Bug分析1.3Bug解决二、心形积分之恋(心形面积计算中的数值积分误差)1.1Bug背景1.1.1背景1.1.2数学模型1.2Bug分析1.2.1初始代码1.2.2代码工作流程图1.2.3代码分析1.3Bug解决三、总结Bug1:多线程环境中的

热文推荐