《AI助力结对编程:使用GitHub Copilot完成Java猜数字游戏实战记录》
摘要:23计科本班小组使用GitHub Copilot进行结对编程,开发Java猜数字游戏。通过注释引导AI生成代码,小组分工协作完成项目初始化、输入验证、游戏循环等功能实现。最终成果展示了一个包含难度选择、异常处理等完整功能的控制台游戏。实践表明,Copilot能显著提升开发效率,但仍需人工审查优化。这种"人机结对"模式既发挥了AI的代码生成优势,又保留了开发者的主导权,为编
班级:23计科本科6班
小组成员:[王乾宇]、[白宇航]、[陈泰宇]、[董原博]
本博客为《软件工程》课程结对编程作业的提交内容。
一、 引言:作业背景与目标
本次作业要求我们2-3人一组,体验使用代码自动生成工具进行结对编程。我们小组选择了GitHub Copilot作为AI编程助手,以经典的“猜数字游戏”作为项目主题,旨在探索AI工具如何影响传统的结对编程流程,并提升编码效率。
二、 准备工作:工欲善其事,必先利其器
-
工具选择:GitHub Copilot
-
简介:GitHub Copilot是由GitHub和OpenAI联合开发的AI代码补全工具,它可以根据代码上下文和自然语言注释生成代码建议。
-
安装:在VSCode或JetBra系列IDE的插件市场搜索安装,需绑定GitHub账户并订阅。
-
-
团队成员与分工
-
驾驶员([姓名1]):主要负责操作IDE,编写注释(Prompt),接受Copilot的代码建议并进行整合。
-
领航员([姓名2]):负责审查Copilot生成的代码,思考整体逻辑,提出优化建议,并记录过程。
-
测试与文档([姓名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();
}
}
-
核心代码结构(最终版概览)
-
GuessNumberGame类:主类 -
initializeGame(): 初始化游戏 -
playGame(): 游戏主逻辑 -
getValidatedInput(int min, int max): 输入验证 -
askPlayAgain(): 询问重复游戏 -
main(String[] args): 程序入口
-
-
程序运行截图
-
五、 总结与反思
-
GitHub Copilot 工具评价
-
优点:
-
提升效率:对于样板代码和常见逻辑,生成速度极快,减少了敲击键盘的时间。
-
启发思路:有时能提供我们未考虑到的实现方式,如优秀的异常处理逻辑。
-
学习助手:生成的代码风格规范,是学习的好参考。
-
-
缺点/注意事项:
-
需严格审查:生成的代码不一定完全正确或最优,必须由开发者进行严格审查和测试。不能盲目相信!
-
过于依赖:可能会削弱初学者对语法和底层逻辑的记忆。
-
-
-
结对编程体验
-
本次“人机结对”是一种新颖的体验。Copilot更像是一个不知疲倦的“初级程序员”,能快速实现需求,而人类队员则需扮演“资深架构师”和“测试工程师”的角色,负责提出需求、把握方向、审查代码和优化逻辑。两者结合,确实提高了开发效率。
-
-
团队收获
-
通过这次作业,我们不仅实践了Java编程,更深刻体会到AI工具在当前开发流程中的定位——强大的辅助者,而非替代者。同时,我们也熟悉了结对编程的合作模式,提升了团队沟通和协作能力。
-
更多推荐





所有评论(0)