班级:23计科本科6班

小组成员:[王乾宇]、[白宇航]、[陈泰宇]、[董原博]

本博客为《软件工程》课程结对编程作业的提交内容。

一、 引言:作业背景与目标

本次作业要求我们2-3人一组,体验使用代码自动生成工具进行结对编程。我们小组选择了GitHub Copilot作为AI编程助手,以经典的“猜数字游戏”作为项目主题,旨在探索AI工具如何影响传统的结对编程流程,并提升编码效率。

二、 准备工作:工欲善其事,必先利其器

  1. 工具选择:GitHub Copilot

    • 简介:GitHub Copilot是由GitHub和OpenAI联合开发的AI代码补全工具,它可以根据代码上下文和自然语言注释生成代码建议。

    • 安装:在VSCode或JetBra系列IDE的插件市场搜索安装,需绑定GitHub账户并订阅。

  2. 团队成员与分工

    • 驾驶员([姓名1]):主要负责操作IDE,编写注释(Prompt),接受Copilot的代码建议并进行整合。

    • 领航员([姓名2]):负责审查Copilot生成的代码,思考整体逻辑,提出优化建议,并记录过程。

    • 测试与文档([姓名3]):负责运行和测试代码,收集截图素材,并参与博客撰写。

  3. 项目主题:Java控制台猜数字游戏

    • 核心功能:程序随机生成一个1-100的数字,玩家在有限次数内猜测,程序根据输入给出“大了”或“小了”的提示。

三、 实战过程:与Copilot的结对编程对话

这是我们博客的核心,我们模拟了与Copilot的交互来生成代码。

步骤1:搭建项目骨架

驾驶员在IDE中创建一个名为GuessNumberGame.java的新文件,并写下初始注释(Prompt):

// 创建一个Java猜数字游戏。需要有一个主类,包含main方法作为入口。

Copilot建议了类的基本结构,我们接受了建议:

public class GuessNumberGame { public static void main(String[] args) { System.out.println("Hello World!"); } }

(此处可附上Copilot代码提示的截图)

步骤2:定义游戏核心属性

领航员提出:“我们需要一些常量来定义数字范围和尝试次数,这样代码更易维护。”

驾驶员写下新的Prompt:

// 定义游戏常量:最小数字1,最大数字100,简单模式尝试次数10,困难模式5次。

Copilot生成了如下代码,我们将其放入类中:

private static final int MAX_ATTEMPTS_EASY = 10; private static final int MAX_ATTEMPTS_HARD = 5; private static final int MIN_NUMBER = 1; private static final int MAX_NUMBER = 100;

(此处可附上代码截图)

步骤3:实现游戏初始化逻辑

驾驶员继续用注释引导Copilot:

// 编写一个initializeGame方法,用于生成随机目标数字,并让玩家选择难度(1为简单,2为困难)。

Copilot几乎完整地生成了我们最终代码里的initializeGame方法,包括Random和Scanner对象的初始化、难度选择逻辑。​ 我们对其进行了微调,使其更符合我们的代码风格。

步骤4:实现输入验证与游戏主循环

这是关键且容易出错的部分。领航员强调:“必须处理用户输入错误,比如输入字母或超出范围数字。”

驾驶员写下Prompt:

// 编写一个getValidatedInput方法,用于获取并验证用户输入,确保是min到max之间的整数。如果输入错误,提示重新输入。 // 然后编写playGame方法,循环猜测,直到猜对或机会用尽。

Copilot出色地生成了包含try-catch异常处理的输入验证方法,以及完整的游戏循环逻辑。​ 生成的代码质量很高,我们只做了少量格式调整。

步骤5:完善与优化

测试员在运行游戏后提出:“一轮游戏结束就退出太不友好了,可以加个重复游玩的功能。”

驾驶员向Copilot提出最终需求:

// 在main方法中,实现游戏结束后询问是否再玩一次,输入y继续,n退出。

Copilot建议使用do-while循环来包裹主游戏逻辑,并生成了askPlayAgain方法。​ 我们采纳了这个清晰的结构。

四、 最终成果展示

经过约一小时的“人机结对”编程,我们得到了一个功能完善、代码健壮的Java游戏。

import java.util.Random;
import java.util.Scanner;

/**
 * 猜数字游戏
 * 班级:23计科本班
 * 小组成员:[王乾宇]、[白宇航]、[陈泰宇]、[董原博]
 * 功能:计算机生成1-100的随机数,玩家有限次数内猜测
 */
public class GuessNumberGame {

    private static final int MAX_ATTEMPTS_EASY = 10;
    private static final int MAX_ATTEMPTS_HARD = 5;
    private static final int MIN_NUMBER = 1;
    private static final int MAX_NUMBER = 100;

    private Random random;
    private Scanner scanner;
    private int targetNumber;
    private int maxAttempts;
    private int guessCount;

    // 构造函数
    public GuessNumberGame() {
        random = new Random();
        scanner = new Scanner(System.in);
    }

    /**
     * 初始化游戏设置
     */
    public void initializeGame() {
        // 生成目标数字
        targetNumber = random.nextInt(MAX_NUMBER) + MIN_NUMBER;
        guessCount = 0;

        System.out.println("=== 欢迎来到猜数字游戏 ===");
        System.out.println("请选择游戏难度:");
        System.out.println("1. 简单模式(10次机会)");
        System.out.println("2. 困难模式(5次机会)");
        System.out.print("请输入你的选择(1或2): ");

        // 获取难度选择
        int choice = getValidatedInput(1, 2);
        if (choice == 1) {
            maxAttempts = MAX_ATTEMPTS_EASY;
            System.out.println("你选择了简单模式,共有" + maxAttempts + "次机会。");
        } else {
            maxAttempts = MAX_ATTEMPTS_HARD;
            System.out.println("你选择了困难模式,共有" + maxAttempts + "次机会。");
        }

        System.out.println("我已经想好了" + MIN_NUMBER + "到" + MAX_NUMBER + "之间的一个数字,开始猜吧!");
    }

    /**
     * 主要的游戏逻辑循环
     */
    public void playGame() {
        while (guessCount < maxAttempts) {
            System.out.printf("\n第 %d 次猜测(还剩 %d 次机会): ",
                    guessCount + 1, maxAttempts - guessCount);

            int guess = getValidatedInput(MIN_NUMBER, MAX_NUMBER);
            guessCount++;

            // 判断猜测结果
            if (guess < targetNumber) {
                System.out.println("猜小了!再大一点!");
            } else if (guess > targetNumber) {
                System.out.println("猜大了!再小一点!");
            } else {
                System.out.printf("🎉 恭喜你!第 %d 次就猜对了数字 %d!\n", guessCount, targetNumber);
                return; // 游戏胜利,直接返回
            }
        }

        // 如果循环结束还没猜对
        System.out.printf("\n💔 很遗憾,机会用完了。正确的数字是 %d。\n", targetNumber);
    }

    /**
     * 获取验证过的用户输入(防止非法输入)
     * @param min 最小值
     * @param max 最大值
     * @return 有效的整数输入
     */
    private int getValidatedInput(int min, int max) {
        while (true) {
            try {
                int input = scanner.nextInt();
                if (input >= min && input <= max) {
                    return input;
                } else {
                    System.out.printf("请输入%d到%d之间的数字: ", min, max);
                }
            } catch (Exception e) {
                System.out.print("输入无效,请输入一个整数: ");
                scanner.next(); // 清除错误的输入
            }
        }
    }

    /**
     * 询问是否再玩一次
     * @return true表示再玩一次,false表示退出
     */
    public boolean askPlayAgain() {
        System.out.print("\n是否再玩一次?(y/n): ");
        String choice = scanner.next().toLowerCase();
        return choice.equals("y") || choice.equals("yes");
    }

    /**
     * 清理资源
     */
    public void cleanup() {
        scanner.close();
        System.out.println("游戏结束,谢谢游玩!");
    }

    /**
     * 主方法 - 程序入口
     */
    public static void main(String[] args) {
        GuessNumberGame game = new GuessNumberGame();
        boolean playAgain;

        do {
            game.initializeGame();
            game.playGame();
            playAgain = game.askPlayAgain();
        } while (playAgain);

        game.cleanup();
    }
}
  1. 核心代码结构(最终版概览)

    • GuessNumberGame类:主类

    • initializeGame(): 初始化游戏

    • playGame(): 游戏主逻辑

    • getValidatedInput(int min, int max): 输入验证

    • askPlayAgain(): 询问重复游戏

    • main(String[] args): 程序入口

  2. 程序运行截图

五、 总结与反思

  1. GitHub Copilot 工具评价

    • 优点

      • 提升效率:对于样板代码和常见逻辑,生成速度极快,减少了敲击键盘的时间。

      • 启发思路:有时能提供我们未考虑到的实现方式,如优秀的异常处理逻辑。

      • 学习助手:生成的代码风格规范,是学习的好参考。

    • 缺点/注意事项

      • 需严格审查:生成的代码不一定完全正确或最优,必须由开发者进行严格审查和测试。不能盲目相信!

      • 过于依赖:可能会削弱初学者对语法和底层逻辑的记忆。

  2. 结对编程体验

    • 本次“人机结对”是一种新颖的体验。Copilot更像是一个不知疲倦的“初级程序员”,能快速实现需求,而人类队员则需扮演“资深架构师”和“测试工程师”的角色,负责提出需求、把握方向、审查代码和优化逻辑。两者结合,确实提高了开发效率。

  3. 团队收获

    • 通过这次作业,我们不仅实践了Java编程,更深刻体会到AI工具在当前开发流程中的定位——强大的辅助者,而非替代者。同时,我们也熟悉了结对编程的合作模式,提升了团队沟通和协作能力。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐