说明:一年前写的作业,感觉挺有意思的,将源码分享给大家。 刚开始看题也觉得很难,不过写着写着思路更加清晰,发现也没有想象中的那么难。
一、作业题目描述:
题目:模拟游戏玩家战斗
1.1 基础功能描述:
假设有两个玩家控制的角色 A 和 B,存在一个怪物 M,A 和 B 的任务是要击败怪物 M,获得胜利。A、B 和 M 的信息如下角色 A:
生命值:100 初始攻击力数值:10,一次只攻击一个目标初始防御力数值:2 当前经验值:1000
当前等级:10 攻击目标时触发暴击的概率为 20%,触发后,攻击力增加 50% 受击时触发护盾的概率为 20%,触发后,防御力增加 10% 角色 B: 生命值:110 初始攻击力数值:12,一次只攻击一次目标 初始防御力数值:3 当前经验值:2000 当前等级:15 攻击目标时触发暴击的概率为 25%,触发后,攻击力增加 30% 受击时触发护盾的概率为 30%,触发后,防御力增加 15% 怪物 M:
生命值:200
初始攻击力数值:8,一次攻击可对多个目标造成同等伤害 初始防御力数值:5 攻击目标时触发暴击的概率为 20%,触发后,攻击力增加 50% 受击时触发护盾的概率为 10%,触发后,防御力增加 10%
1.2 奖励功能描述:
只有角色战斗胜利时,才可发放奖励。
奖励有两种方案:rwd-a 和 rwd-b,其中触发 rwd-a 的概率是 40%,触发 rwd-b 的概率是 60%
奖励方案 rwd-a:
在以下 5 种物品中根据概率抽取一个奖励给玩家,同时获得 200*当前等级 的经验值。物品列表和概率如下:
物品 | 概率 |
金刚石 | 20% |
红宝石 | 20% |
乾坤袋 | 10% |
如意丹 | 20% |
金柳露 | 30% |
奖励方案 rwd-b:
在以下 6 种奖励中根据概率抽取一个奖励给玩家,同时获得 100*当前等级 的经验值。物品列表和概率如下:
物品 | 概率 |
净瓶甘露 | 10% |
人参果 | 10% |
藏宝图 | 30% |
黑宝石 | 20% |
上古灵符 | 15% |
避水珠 | 15% |
1.3 战斗规则:
- 从 main 方法主入口开启模拟战斗
- 当怪物 M 的生命值为 0 时,战斗胜利,调用奖励系统给角色 A 和 B 发放奖励(发放逻辑见上述的奖励系统描述),程序结束
- 当角色 A 和 B 的生命值都为 0 时,战斗失败,程序结束
- 当某个对象生命值为 0,且战斗未结束时,该对象不能再进行攻击
- 每次被攻击对象受到的伤害值 = 攻击者当前的攻击力 – 被攻击者当前的防御力
- 同时攻击力和暴击概率有关,防御力和护盾概率有关,每次攻击时要重新计算伤害值
- A、B 和 M 每次的出手攻击顺序,可以指定顺序,也可以随机顺序
1.4 作业要求:
- 使用 Java 面向对象的程序设计方式(包含封装、继承和多态特性)模拟实现上述战斗逻辑
- 将每次攻击的过程(A、B 和 M 的攻击力,防御力,受到攻击的伤害值和剩余的生命值,以及攻击对象)打印出来,输出格式不限,但要清晰直观
- 战斗胜利时(可自行调整数值,一定要跑到一次战斗胜利),将奖励信息打印出来(包括调用了哪种奖励方案,最终获得了哪些奖励),输出格式不限,但要清晰直观
二、写作业
说明:当时只想着快点写完所以写的比较冗余,各角色的操作直接写在了Main.java中了,最后也是用了一个多小时完成了。
2.1 文件格式:
|---- gameFight
|---- src
|---- role
|---- role.java
|---- roleMonster.java
|---- rolePlayer.java
|---- Main.java
2.2 代码:
2.2.1 role.java :
package role;
public class role {
private String name;
private float health; //生命值
private float primaryAttack; //初始攻击力
private float pirmaryDefense; //初始防御
private float criticalAttack; //暴击时的攻击力
private float criticalDefense; //触发防御加强
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getHealth() {
return health;
}
public void setHealth(float health) {
this.health = health;
}
public float getPrimaryAttack() {
return primaryAttack;
}
public void setPrimaryAttack(float primaryAttack) {
this.primaryAttack = primaryAttack;
}
public float getPirmaryDefense() {
return pirmaryDefense;
}
public void setPirmaryDefense(float pirmaryDefense) {
this.pirmaryDefense = pirmaryDefense;
}
public float getCriticalAttack() {
return criticalAttack;
}
public void setCriticalAttack(float criticalAttack) {
this.criticalAttack = criticalAttack;
}
public float getCriticalDefense() {
return criticalDefense;
}
public void setCriticalDefense(float criticalDefense) {
this.criticalDefense = criticalDefense;
}
}
2.2.2 roleMonster.java :
package role;
public class roleMonster extends role{
public roleMonster(String name,float health,float primaryAttack,float primaryDefense,float criticalAttack,float criticalDenfense) {
this.setName(name);
this.setHealth(health);
this.setPrimaryAttack(primaryAttack);
this.setPirmaryDefense(primaryDefense);
this.setCriticalAttack(criticalAttack);
this.setCriticalDefense(criticalDenfense);
}
}
2.2.3 rolePlayer.java :
package role;
public class rolePlayer extends role{
private int experience; //当前经验值
private int grade; //当前等级
public rolePlayer(String name,float health,float primaryAttack,float primartDefense,int experience, int grade ,float criticalAttack,float criticalDenfense) {
this.setName(name);
this.setHealth(health);
this.setPrimaryAttack(primaryAttack);
this.setPirmaryDefense(primartDefense);
this.experience = experience;
this.grade = grade;
this.setCriticalAttack(criticalAttack);
this.setCriticalDefense(criticalDenfense);
}
public int getExperience() {
return experience;
}
public void setExperience(int experience) {
this.experience = experience;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}
2.2.4 Main.java
import role.roleMonster;
import role.rolePlayer;
import java.util.Random;
public class Main {
public static void main(String[] args) {
//创建玩家roleA,roleB 怪兽roleM
roleMonster roleM = new roleMonster("roleM",200,8,5, (float) (8*1.5), (float) (5*1.1));
rolePlayer roleA = new rolePlayer("roleA",100,10,2,1000,10,(float)(10*1.5),(float)(2*1.1));
rolePlayer roleB = new rolePlayer("roleB",110,12,3,2000,15,(float) (12*1.3),(float) (3*1.15));
//战斗过程
fightProcess(roleA,roleB,roleM);
//结束战斗过程后,如果怪兽roleM的生命值还大于0则存活,说明玩家被怪兽打败,玩家拿不到奖励
if (roleM.getHealth()>0){
System.out.println("战斗失败!");
}else{
System.out.println("战斗成功!");
//结束战斗后如果玩家roleA还存活则获得奖品
getReward(roleA);
//结束战斗后如果玩家roleB还存活则获得奖品
getReward(roleB);
}
}
//p1代表攻击目标时触发暴击的概率,因为p的取值为为0-1,如果p1大于p的取值范围则不触发,小于等于则触发
static boolean raiseAttack(double p1){
Random rand = new Random();
float p = rand.nextFloat();
if(p>p1){
return false;
}else{
return true;
}
}
//p2代表受击时触发护盾的概率,因为p的取值为为0-1,如果p2大于p的取值范围则不触发,小于等于则触发
static boolean raiseDefense(double p2){
Random rand = new Random();
float p = rand.nextFloat();
if(p>p2){
return false;
}else{
return true;
}
}
static void fightProcess(rolePlayer roleA,rolePlayer roleB,roleMonster roleM){
boolean raiseAttack;
boolean raiseDefense;
//结束条件是玩家roleA和玩家roleB的都为死亡状态或者怪兽roleM为死亡状态 (血量同时小于等于0为死亡状态)
while((roleA.getHealth()>0||roleB.getHealth()>0)&&roleM.getHealth()>0){
//因为可以指定攻击顺序,这里我就让指定攻击顺序为roleA,roleB,roleM
//如果玩家roleA存在和怪兽roleM都存在,roleA才能对怪兽roleM进行攻击
if(roleA.getHealth()>0&&roleM.getHealth()>0){
raiseAttack=raiseAttack(0.2); //roleA攻击目标时触发暴击的概率为 20%
raiseDefense=raiseDefense(0.1); //roleM受击时触发护盾的概率为 10%
//如果roleA不触发暴击攻击和roleM不触发提高防御
if(!raiseAttack &&!raiseDefense){
roleM.setHealth(roleM.getHealth()-(roleA.getPrimaryAttack()-roleM.getPirmaryDefense()));
printProcess(roleA,roleM,"000");
}
//如果roleA不触发暴击攻击和roleM触发提高防御
if(!raiseAttack && raiseDefense) {
roleM.setHealth(roleM.getHealth()-(roleA.getPrimaryAttack()-roleM.getCriticalDefense()));
printProcess(roleA,roleM,"001");
}
//如果roleA触发暴击攻击和roleM不触发提高防御
if(raiseAttack &&!raiseDefense){
roleM.setHealth(roleM.getHealth()-(roleA.getCriticalAttack()-roleM.getPirmaryDefense()));
printProcess(roleA,roleM,"010");
}
//如果roleA触发暴击攻击和roleM触发提高防御
if(raiseAttack && raiseDefense){
roleM.setHealth(roleM.getHealth()-(roleA.getCriticalAttack()-roleM.getCriticalDefense()));
printProcess(roleA,roleM,"011");
}
}
//如果玩家roleB存在和怪兽roleM都存在,roleB才能对怪兽roleM进行攻击
if(roleB.getHealth()>0&&roleM.getHealth()>0){
raiseAttack=raiseAttack(0.25); //roleB攻击目标时触发暴击的概率为 25%
raiseDefense=raiseDefense(0.1); //roleM受击时触发护盾的概率为 10%
//如果roleB不触发暴击攻击和roleM不触发提高防御
if(!raiseAttack &&!raiseDefense){
roleM.setHealth(roleM.getHealth()-(roleB.getPrimaryAttack()-roleM.getPirmaryDefense()));
printProcess(roleB,roleM,"000");
}
//如果roleB不触发暴击攻击和roleM触发提高防御
if(!raiseAttack && raiseDefense){
roleM.setHealth(roleM.getHealth()-(roleB.getPrimaryAttack()-roleM.getCriticalDefense()));
printProcess(roleB,roleM,"001");
}
//如果roleB触发暴击攻击和roleM不触发提高防御
if(raiseAttack &&!raiseDefense){
roleM.setHealth(roleM.getHealth()-(roleB.getCriticalAttack()-roleM.getPirmaryDefense()));
printProcess(roleB,roleM,"010");
}
//如果roleB触发暴击攻击和roleM触发提高防御
if(raiseAttack && raiseDefense){
roleM.setHealth(roleM.getHealth()-(roleB.getCriticalAttack()-roleM.getCriticalDefense()));
printProcess(roleB,roleM,"011");
}
}
//若怪兽还存活,则进行攻击玩家,玩家roleA还存活则受到怪兽roleM的攻击
if(roleM.getHealth()>0&&roleA.getHealth()>0){
raiseAttack=raiseAttack(0.2); roleM攻击目标时触发暴击的概率为 20%
raiseDefense=raiseDefense(0.2); //roleA受击时触发护盾的概率为 20%,
//如果roleM不触发暴击攻击和roleA不触发提高防御
if(!raiseAttack &&!raiseDefense){
roleA.setHealth(roleA.getHealth()-(roleM.getPrimaryAttack()-roleA.getPirmaryDefense()));
printProcess(roleA,roleM,"100");
}
//如果roleM不触发暴击攻击和roleA触发提高防御
if(!raiseAttack && raiseDefense){
roleA.setHealth(roleA.getHealth()-(roleM.getPrimaryAttack()-roleA.getCriticalDefense()));
printProcess(roleA,roleM,"101");
}
//如果roleM触发暴击攻击和roleA不触发提高防御
if(raiseAttack &&!raiseDefense){
roleA.setHealth(roleA.getHealth()-(roleM.getCriticalAttack()-roleA.getPirmaryDefense()));
printProcess(roleA,roleM,"110");
}
//如果roleM触发暴击攻击和roleA触发提高防御
if(raiseAttack && raiseDefense){
roleA.setHealth(roleA.getHealth()-(roleM.getCriticalAttack()-roleA.getCriticalDefense()));
printProcess(roleA,roleM,"111");
}
}
//若怪兽还存活,则进行攻击玩家,玩家roleB还存活则受到怪兽roleM的攻击
if(roleM.getHealth()>0&&roleB.getHealth()>0){
raiseAttack=raiseAttack(0.2); //roleM攻击目标时触发暴击的概率为 20%
raiseDefense=raiseDefense(0.3); //roleB受击时触发护盾的概率为 30%,
//如果roleM不触发暴击攻击和roleB不触发提高防御
if(!raiseAttack && !raiseDefense){
roleB.setHealth(roleB.getHealth()-(roleM.getPrimaryAttack()-roleB.getPirmaryDefense()));
printProcess(roleB,roleM,"100");
}
//如果roleM不触发暴击攻击和roleB触发提高防御
if(!raiseAttack && raiseDefense){
roleB.setHealth(roleB.getHealth()-(roleM.getPrimaryAttack()-roleB.getCriticalDefense()));
printProcess(roleB,roleM,"101");
}
//如果roleM触发暴击攻击和roleB不触发提高防御
if(raiseAttack && !raiseDefense){
roleB.setHealth(roleB.getHealth()-(roleM.getCriticalAttack()-roleB.getPirmaryDefense()));
printProcess(roleB,roleM,"110");
}
//如果roleM触发暴击攻击和roleB触发提高防御
if(raiseAttack && raiseDefense){
roleB.setHealth(roleB.getHealth()-(roleM.getCriticalAttack()-roleB.getCriticalDefense()));
printProcess(roleB,roleM,"111");
}
}
}
}
static void getReward(rolePlayer role){
if(role.getHealth()>0){
Random rand = new Random();
int p = rand.nextInt(10);
//获得p<4时获得pwd-a的奖励,否则获得pwd-b的奖励
if(p<4){
role.setExperience(role.getExperience()+role.getGrade()*200); //获取相应经验值
System.out.print("玩家"+role.getName()+"获得奖励方案pwd-a的经验值:"+role.getGrade()*200);
int p1 = rand.nextInt(100);
System.out.print(" 获得物品奖励: ");
if(p1<20){
System.out.println("金刚石");
}else if(p1<40){
System.out.println("红宝石");
}else if(p1<50){
System.out.println("乾坤袋");
}else if(p1<70){
System.out.println("如意丹");
}else{
System.out.println("金柳露");
}
}else{
role.setExperience(role.getExperience()+role.getGrade()*100);
System.out.print("玩家"+role.getName()+"获得奖励方案pwd-b的经验值:"+role.getGrade()*100);
int p1 = rand.nextInt(100);
System.out.print(" 获得物品奖励: ");
if(p1<10){
System.out.println("净瓶甘露");
}else if(p1<20){
System.out.println("人参果");
}else if(p1<50){
System.out.println("藏宝图");
}else if(p1<70){
System.out.println("黑宝石");
}else if(p1<85){
System.out.println("上古灵符");
}else{
System.out.println("避水珠");
}
}
}
}
/*输出每个战斗过程结果,signal的百位:0表示玩家攻击怪兽,1表示怪兽攻击玩家;
signal的十位是代表攻击方:0表示是普通攻击,1表示暴击攻击;signal的个位是代表防守方:0表示普通防御,1表示触发护盾提高防御;
例如:signal=011 是玩家攻击怪兽,玩家暴击攻击怪兽,同时怪兽触发护盾提高防御*/
static void printProcess(rolePlayer player,roleMonster monster,String signal){
switch (signal){
case "000":
System.out.println(
"攻击方:\n玩家:"+player.getName()
+ "\n玩家的血量:"+player.getHealth()
+ "\n玩家的攻击力:"+player.getPrimaryAttack());
System.out.println(
"防御方:\n怪兽:"+monster.getName()
+"\n怪兽受到的伤害:"+(player.getPrimaryAttack()- monster.getPirmaryDefense())
+"\n怪兽剩余的血量:"+monster.getHealth()
+"\n怪兽的防御力:"+monster.getPirmaryDefense());
break;
case "001":
System.out.println(
"攻击方:\n玩家:"+player.getName()
+ "\n玩家的血量:"+player.getHealth()
+ "\n玩家的攻击力:"+player.getPrimaryAttack());
System.out.println(
"防御方:\n怪兽:"+monster.getName()
+"\n怪兽受到的伤害:"+(player.getPrimaryAttack()- monster.getCriticalDefense())
+"\n怪兽剩余的血量:"+monster.getHealth()
+"\n怪兽的防御力:"+monster.getCriticalDefense());
break;
case "010":
System.out.println(
"攻击方:\n玩家:"+player.getName()
+ "\n玩家的血量:"+player.getHealth()
+ "\n玩家的攻击力:"+player.getCriticalAttack());
System.out.println(
"防御方:\n怪兽:"+monster.getName()
+"\n怪兽受到的伤害:"+(player.getCriticalAttack()- monster.getPirmaryDefense())
+"\n怪兽剩余的血量:"+monster.getHealth()
+"\n怪兽的防御力:"+monster.getPirmaryDefense());
break;
case "011":
System.out.println(
"攻击方:\n玩家:"+player.getName()
+ "\n玩家的血量:"+player.getHealth()
+ "\n玩家的攻击力:"+player.getCriticalAttack());
System.out.println(
"防御方:\n怪兽:"+monster.getName()
+"\n怪兽受到的伤害:"+(player.getCriticalAttack()- monster.getCriticalDefense())
+"\n怪兽剩余的血量:"+monster.getHealth()
+"\n怪兽的防御力:"+monster.getCriticalDefense());
break;
case "100":
System.out.println(
"攻击方:\n怪兽:"+monster.getName()
+ "\n怪兽的血量:"+monster.getHealth()
+ "\n怪兽的攻击力:"+monster.getPrimaryAttack());
System.out.println(
"防守方:\n玩家:"+player.getName()
+"\n玩家受到的伤害:"+(monster.getPrimaryAttack() - player.getPirmaryDefense())
+ "\n玩家剩余的血量:"+player.getHealth()
+"\n玩家的防御力:"+player.getPirmaryDefense());
break;
case "101":
System.out.println(
"攻击方:\n怪兽:"+monster.getName()
+ "\n怪兽的血量:"+monster.getHealth()
+ "\n怪兽的攻击力:"+monster.getPrimaryAttack());
System.out.println(
"防守方:\n玩家:"+player.getName()
+"\n玩家受到的伤害:"+(monster.getPrimaryAttack() - player.getCriticalDefense())
+ "\n玩家剩余的血量:"+player.getHealth()
+"\n玩家的防御力:"+player.getCriticalDefense());
break;
case "110":
System.out.println(
"攻击方:\n怪兽:"+monster.getName()
+ "\n怪兽的血量:"+monster.getHealth()
+ "\n怪兽的攻击力:"+monster.getCriticalAttack());
System.out.println(
"防守方:\n玩家:"+player.getName()
+"\n玩家受到的伤害:"+(monster.getCriticalAttack() - player.getPirmaryDefense())
+ "\n玩家剩余的血量:"+player.getHealth()
+"\n玩家的防御力:"+player.getPirmaryDefense());
break;
case "111":
System.out.println(
"攻击方:\n怪兽:"+monster.getName()
+ "\n怪兽的血量:"+monster.getHealth()
+ "\n怪兽的攻击力:"+monster.getCriticalAttack());
System.out.println(
"防守方:\n玩家:"+player.getName()
+"\n玩家受到的伤害:"+(monster.getCriticalAttack() - player.getCriticalDefense())
+ "\n玩家剩余的血量:"+player.getHealth()
+"\n玩家的防御力:"+player.getCriticalDefense());
break;
}
System.out.println();
}
}