3天精通文本游戏开发:从基础到15种手势的Python实战指南

3天精通文本游戏开发:从基础到15种手势的Python实战指南

【免费下载链接】100daysofcode-with-python-course Course materials and handouts for #100DaysOfCode in Python course 【免费下载链接】100daysofcode-with-python-course 项目地址: https://gitcode.com/gh_mirrors/10/100daysofcode-with-python-course

你还在为如何将面向对象编程应用到实际项目中而烦恼吗?还在寻找既能巩固知识点又有趣的编程练习吗?本文将通过3天时间,带你从零构建一个完整的文本游戏系统,从经典的"石头剪刀布"到复杂的15种手势版本,全面掌握Python类设计、游戏逻辑实现和数据驱动开发。读完本文你将获得:

  • 面向对象编程(OOP)的实战经验
  • 游戏循环与状态管理的核心逻辑
  • CSV数据解析与动态配置应用
  • 从简单到复杂系统的迭代开发能力

项目概述与准备工作

本项目是"100天Python编程挑战"的第13-15天内容,专注于文本交互游戏的开发。我们将通过构建两个版本的"石头剪刀布"游戏,逐步掌握Python面向对象编程和游戏开发的核心概念。

技术栈与环境配置

# 克隆项目仓库
git clone https://gitcode.com/gh_mirrors/10/100daysofcode-with-python-course

# 进入项目目录
cd 100daysofcode-with-python-course/days/13-15-text-games

项目结构解析

13-15-text-games/
├── README.md           # 任务说明文档
├── data/
│   ├── battle-table.csv # 15种手势胜负关系数据
│   └── sample_reader.py # CSV解析示例代码
└── dnd_game/           # 额外文本游戏示例(可选扩展)

Day 13:面向对象基础与项目初始化

核心类设计

文本游戏的核心在于对游戏实体和规则的抽象。我们需要设计两个基础类:Roll(手势)和Player(玩家)。

mermaid

项目初始化实现

首先创建游戏入口文件rps_game.py,实现基础框架:

class Roll:
    def __init__(self, name):
        self.name = name
        self.defeats = []  # 能击败的手势列表
        self.defeated_by = []  # 被击败的手势列表
    
    def can_defeat(self, other_roll):
        """判断当前手势是否能击败另一个手势"""
        return other_roll.name in self.defeats
    
    def is_defeated_by(self, other_roll):
        """判断当前手势是否被另一个手势击败"""
        return other_roll.name in self.defeated_by


class Player:
    def __init__(self, name):
        self.name = name
        self.score = 0
    
    def get_name(self):
        return self.name
    
    def increment_score(self):
        self.score += 1
    
    def get_score(self):
        return self.score


def print_header():
    """打印游戏标题头"""
    print("=" * 40)
    print("      石头剪刀布游戏 v1.0")
    print("=" * 40)
    print()


def get_player_name():
    """获取玩家姓名"""
    return input("请输入你的名字: ").strip()


def main():
    print_header()
    name = get_player_name()
    
    # 创建玩家
    player = Player(name)
    computer = Player("电脑")
    
    print(f"\n欢迎 {player.get_name()}! 准备和{computer.get_name()}对战吧!")

if __name__ == "__main__":
    main()

Day 14:基础版石头剪刀布实现

游戏核心逻辑

基础版游戏包含三种手势:石头(Rock)、剪刀(Scissors)和布(Paper),它们之间的胜负关系如下:

mermaid

手势关系实现

扩展Roll类,添加手势间的胜负关系定义:

def build_basic_rolls():
    """创建基础版的三种手势及其关系"""
    # 创建手势实例
    rock = Roll("Rock")
    scissors = Roll("Scissors")
    paper = Roll("Paper")
    
    # 定义胜负关系
    rock.defeats = [scissors.name]
    rock.defeated_by = [paper.name]
    
    scissors.defeats = [paper.name]
    scissors.defeated_by = [rock.name]
    
    paper.defeats = [rock.name]
    paper.defeated_by = [scissors.name]
    
    return [rock, scissors, paper]

游戏循环实现

实现游戏的主要流程控制逻辑:

import random

def player_choose_roll(rolls):
    """玩家选择手势"""
    print("\n请选择手势:")
    for i, roll in enumerate(rolls, 1):
        print(f"{i}. {roll.name}")
    
    while True:
        try:
            choice = int(input(f"输入选项(1-{len(rolls)}): ")) - 1
            if 0 <= choice < len(rolls):
                return rolls[choice]
            print(f"请输入1到{len(rolls)}之间的数字")
        except ValueError:
            print("请输入有效的数字")


def computer_choose_roll(rolls):
    """电脑随机选择手势"""
    return random.choice(rolls)


def determine_winner(p1_roll, p2_roll):
    """判断一轮的胜负"""
    if p1_roll.name == p2_roll.name:
        return None  # 平局
    
    if p2_roll.name in p1_roll.defeats:
        return "player1"
    return "player2"


def game_loop(player1, player2, rolls, rounds=3):
    """游戏主循环"""
    current_round = 1
    
    while current_round <= rounds:
        print(f"\n===== 第 {current_round} 轮 =====")
        
        # 选择手势
        p1_roll = player_choose_roll(rolls)
        p2_roll = computer_choose_roll(rolls)
        
        # 显示选择
        print(f"\n{player1.get_name()} 选择了: {p1_roll.name}")
        print(f"{player2.get_name()} 选择了: {p2_roll.name}")
        
        # 判断胜负
        winner = determine_winner(p1_roll, p2_roll)
        
        if winner is None:
            print("这一轮是平局!")
        else:
            if winner == "player1":
                player1.increment_score()
                print(f"{player1.get_name()} 赢得了这一轮!")
            else:
                player2.increment_score()
                print(f"{player2.get_name()} 赢得了这一轮!")
        
        # 显示当前比分
        print(f"比分: {player1.get_name()} {player1.get_score()} - {player2.get_score()} {player2.get_name()}")
        
        current_round += 1
    
    # 确定最终赢家
    print("\n===== 游戏结束 =====")
    if player1.get_score() > player2.get_score():
        print(f"恭喜 {player1.get_name()} 获胜!")
    elif player2.get_score() > player1.get_score():
        print(f"{player2.get_name()} 获胜!")
    else:
        print("游戏以平局结束!")


# 更新main函数
def main():
    print_header()
    rolls = build_basic_rolls()
    name = get_player_name()
    
    player1 = Player(name)
    player2 = Player("Computer")
    
    game_loop(player1, player2, rolls)

if __name__ == "__main__":
    main()

Day 15:代码优化与进阶版实现

基础版代码优化

对现有代码进行重构,提高可维护性和可扩展性:

  1. 添加类型注解,提高代码可读性
  2. 优化异常处理,增强程序健壮性
  3. 提取重复逻辑为辅助函数

进阶版:15种手势实现

进阶版游戏包含15种手势,其胜负关系通过CSV文件定义。这种数据驱动的方式使游戏更易于扩展。

CSV数据解析

使用Python的csv模块解析手势关系数据:

import csv
from typing import List, Dict

def load_rolls_from_csv(file_path: str) -> List[Roll]:
    """从CSV文件加载15种手势及其关系"""
    rolls = {}
    
    # 读取CSV文件并创建所有手势
    with open(file_path, 'r') as f:
        reader = csv.DictReader(f)
        for row in reader:
            roll_name = row['Attacker']
            rolls[roll_name] = Roll(roll_name)
    
    # 再次读取CSV以设置胜负关系
    with open(file_path, 'r') as f:
        reader = csv.DictReader(f)
        for row in reader:
            attacker_name = row['Attacker']
            attacker_roll = rolls[attacker_name]
            
            for defender_name, result in row.items():
                if defender_name == 'Attacker' or defender_name == attacker_name:
                    continue
                    
                if result.strip().lower() == 'win':
                    attacker_roll.defeats.append(defender_name)
                elif result.strip().lower() == 'lose':
                    attacker_roll.defeated_by.append(defender_name)
    
    return list(rolls.values())
15种手势游戏流程

mermaid

集成进阶版到主程序
def main():
    print_header()
    
    # 让用户选择游戏版本
    print("请选择游戏版本:")
    print("1. 基础版 (石头、剪刀、布)")
    print("2. 进阶版 (15种手势)")
    
    while True:
        choice = input("输入选项 (1/2): ").strip()
        if choice == '1':
            rolls = build_basic_rolls()
            break
        elif choice == '2':
            try:
                rolls = load_rolls_from_csv('data/battle-table.csv')
                break
            except FileNotFoundError:
                print("找不到进阶版数据文件,请确保data目录下有battle-table.csv")
                print("将使用基础版游戏...")
                rolls = build_basic_rolls()
                break
        else:
            print("请输入1或2选择游戏版本")
    
    name = get_player_name()
    player1 = Player(name)
    player2 = Player("Computer")
    
    # 进阶版游戏增加回合数
    rounds = 5 if len(rolls) > 3 else 3
    game_loop(player1, player2, rolls, rounds)

15种手势对比表

部分手势及其胜负关系示例:

手势能击败被击败
RockScissors, Sponge, Wolf, Tree, HumanGun, Lightning, Devil, Dragon, Water, Air, Paper, Fire
GunLightning, Devil, Dragon, Water, Air, Paper, SpongeRock, Wolf, Tree, Human, Snake, Scissors, Fire
PaperRock, Gun, Lightning, Devil, Dragon, Water, AirScissors, Fire, Sponge, Wolf, Tree, Human, Snake

项目扩展与学习资源

功能扩展建议

  1. 多人对战模式:添加本地多人对战功能,支持两人轮流操作
  2. 游戏难度设置:为电脑玩家添加不同难度级别(简单、中等、困难)
  3. 历史记录:使用文件系统或数据库保存游戏记录
  4. 图形界面:使用Tkinter或PyQt为游戏添加简单的图形界面

进阶学习路径

mermaid

常见问题解决

  1. CSV文件路径问题:确保CSV文件路径正确,或使用绝对路径
  2. 手势关系复杂:通过print语句调试胜负关系是否正确加载
  3. 用户输入验证:增强输入处理,防止无效输入导致程序崩溃

总结与成果展示

通过这三天的学习,我们从基础的"石头剪刀布"游戏,逐步扩展到包含15种手势的复杂版本,掌握了以下技能:

  • 面向对象编程思想的实际应用
  • 游戏核心逻辑与状态管理
  • 数据驱动开发(通过CSV文件动态配置游戏规则)
  • 代码重构与优化技巧

最终代码结构

rps_game.py           # 游戏主程序
data/
  battle-table.csv    # 15种手势关系数据

运行示例

========================================
      石头剪刀布游戏 v1.0
========================================

请选择游戏版本:
1. 基础版 (石头、剪刀、布)
2. 进阶版 (15种手势)
输入选项 (1/2): 2

请输入你的名字: Alice

===== 第 1 轮 =====

请选择手势:
1. Rock
2. Gun
3. Lightning
4. Devil
5. Dragon
6. Water
7. Air
8. Paper
9. Sponge
10. Wolf
11. Tree
12. Human
13. Snake
14. Scissors
15. Fire
输入选项(1-15): 3

Alice 选择了: Lightning
Computer 选择了: Tree

Lightning 击败了 Tree!
Alice 赢得了这一轮!
比分: Alice 1 - 0 Computer

现在你已经掌握了文本游戏开发的核心技术。继续探索,你可以创建更复杂的角色扮演游戏(RPG)或策略游戏。记得在社交媒体上分享你的成果,并标记#100DaysOfCode话题!

【免费下载链接】100daysofcode-with-python-course Course materials and handouts for #100DaysOfCode in Python course 【免费下载链接】100daysofcode-with-python-course 项目地址: https://gitcode.com/gh_mirrors/10/100daysofcode-with-python-course

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值