C#坦克对战程序问题:数组坦克属性无法在循环中正常复用
问题:坦克对战项目中随机属性无法在攻击逻辑中生效
我正在开发一个坦克对战作业项目,在Tankstat类的Tankcreate方法中,通过以下方式创建带随机属性的坦克数组:
pantera[0] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100));
但在attack方法的攻击逻辑中,使用如下while循环时:
while (ammunition > 0 && armor > 0 && maneuver > 0)
调试发现ammunition、armor、maneuver始终初始为0,而非创建时生成的0-100随机值,导致攻击后属性变为负数。请问如何让数组中坦克的随机属性值能在for/while循环逻辑中正常使用?
附完整代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace C { class Tankstat { private string name { get; set; } private int ammunition { get; set; } private int armor { get; set; } private int maneuver { get; set; } private int ammunitionMinus { get; set; } private int armorMinus { get; set; } private int maneuverMinus { get; set; } public Tankstat(string name, int ammunition, int armor, int maneuver) { this.name = name; this.ammunition = ammunition; this.armor = armor; this.maneuver = maneuver; } public override string ToString() { return $"The name of the tank is {name} the amount of ammunition left is {ammunition} the strength of armor is {armor} the maneuver level is {maneuver}"; } public static Tankstat operator *(Tankstat tank1, Tankstat tank2) { return tank1 * tank2; } public static Tankstat operator ^ (Tankstat tank1, Tankstat tank2) { return tank1 ^ tank2; } public Tankstat() { } public void Tankcreate() { Random rand = new Random(); Tankstat[] pantera = new Tankstat[5]; pantera[0] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); pantera[1] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); pantera[2] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); pantera[3] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); pantera[4] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); Tankstat[] T34 = new Tankstat[5]; T34[0] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[1] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[2] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[3] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[4] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); foreach (Tankstat panteras in pantera) { Console.WriteLine(panteras); } foreach (Tankstat T34S in T34) { Console.WriteLine(T34S); } } Tankstat[] pantera = new Tankstat[5]; Tankstat[] T34 = new Tankstat[5]; public void attack() { for (int i = 0; i < pantera.Length && i < T34.Length; i++) { while (ammunition > 0 && armor > 0 && maneuver > 0) Console.WriteLine("Initializer is going to attack the tank"); Random rambo = new Random(); ammunitionMinus = rambo.Next(1, 20); ammunition = ammunition - ammunitionMinus; armorMinus = rambo.Next(1, 10); armor = armor - armorMinus; maneuverMinus = rambo.Next(2, 15); maneuver = maneuver - maneuverMinus; Console.WriteLine($"The name of the tank {name} has {ammunition} ammunition left the armor is {armor} and the manuever is {maneuver}, wait for 2 seconds for next move"); Thread.Sleep(2000); } } } }
解决方案
问题根源
- 数组作用域冲突:
Tankcreate方法内部重新定义了pantera和T34数组,与类级别的同名数组是完全独立的变量。方法内创建的坦克实例仅存在于局部作用域,类级别的数组始终是未初始化的空实例(默认属性值为0)。 - 未正确引用数组中的坦克实例:
attack方法直接访问当前Tankstat对象自身的属性,而非数组中存储的具体坦克实例的属性。 - while循环语法错误:while循环后缺少大括号,仅
Console.WriteLine属于循环,属性修改代码直接执行,且循环条件永远无法终止(初始值为0时直接跳过)。 - 属性访问权限不足:
ammunition等属性为private,无法在类内的其他方法中直接访问数组中坦克实例的属性。 - 运算符重载无限递归:
*和^运算符重载直接调用自身,会导致栈溢出。
修改步骤
1. 统一数组作用域
删除Tankcreate方法内的局部数组定义,直接使用类级别的数组:
public void Tankcreate() { Random rand = new Random(); // 直接使用类级别的数组,不再重新定义 pantera[0] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); pantera[1] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); pantera[2] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); pantera[3] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); pantera[4] = new Tankstat("Pantera", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[0] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[1] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[2] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[3] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); T34[4] = new Tankstat("T-34", rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100)); foreach (Tankstat panteras in pantera) { Console.WriteLine(panteras); } foreach (Tankstat T34S in T34) { Console.WriteLine(T34S); } }
2. 正确引用数组中的坦克实例
在attack方法中通过数组索引获取具体坦克对象,修改其属性:
public void attack() { Random rambo = new Random(); // 只初始化一次Random,避免重复随机值 for (int i = 0; i < pantera.Length && i < T34.Length; i++) { Tankstat attackingTank = pantera[i]; Tankstat defendingTank = T34[i]; // 攻击循环:直到攻击方弹药耗尽,或防守方装甲/机动为0 while (attackingTank.ammunition > 0 && defendingTank.armor > 0 && defendingTank.maneuver > 0) { Console.WriteLine($"{attackingTank.name} 正在攻击 {defendingTank.name}"); // 攻击方消耗弹药 int ammoLoss = rambo.Next(1, 20); attackingTank.ammunition -= ammoLoss; if (attackingTank.ammunition < 0) attackingTank.ammunition = 0; // 防守方损失装甲和机动 int armorLoss = rambo.Next(1, 10); defendingTank.armor -= armorLoss; if (defendingTank.armor < 0) defendingTank.armor = 0; int maneuverLoss = rambo.Next(2, 15); defendingTank.maneuver -= maneuverLoss; if (defendingTank.maneuver < 0) defendingTank.maneuver = 0; Console.WriteLine($"{attackingTank.name} 剩余弹药: {attackingTank.ammunition}"); Console.WriteLine($"{defendingTank.name} 剩余装甲: {defendingTank.armor}, 剩余机动: {defendingTank.maneuver}"); Console.WriteLine("等待2秒进行下一回合攻击..."); Thread.Sleep(2000); } Console.WriteLine($"对战结束: {attackingTank.name} vs {defendingTank.name}\n"); } }
3. 修改属性访问权限
将name、ammunition等属性的访问修饰符改为public,允许类内其他方法访问:
public string name { get; set; } public int ammunition { get; set; } public int armor { get; set; } public int maneuver { get; set; }
4. 修复或删除错误的运算符重载
当前的运算符重载会导致无限递归,可删除或实现实际逻辑:
// 删除无效的运算符重载,或替换为实际逻辑 // public static Tankstat operator *(Tankstat tank1, Tankstat tank2) // { // // 示例逻辑:返回弹药翻倍的新坦克 // return new Tankstat(tank1.name, tank1.ammunition * 2, tank1.armor, tank1.maneuver); // }
额外优化建议
- Random实例复用:在类级别初始化
Random,避免循环中重复创建导致的重复随机值。 - 代码复用:将创建坦克的逻辑封装为单独方法,减少重复代码。
- 边界值处理:所有属性修改时确保数值不低于0,避免负数属性。
内容的提问来源于stack exchange,提问作者Larrythelobster
相关产品推荐
相关产品推荐

