diff --git a/logic/GameClass/GameObj/Areas/Asteroid.cs b/logic/GameClass/GameObj/Areas/Asteroid.cs
index 4f0b12b6..8d9776f2 100755
--- a/logic/GameClass/GameObj/Areas/Asteroid.cs
+++ b/logic/GameClass/GameObj/Areas/Asteroid.cs
@@ -3,12 +3,9 @@
namespace GameClass.GameObj.Areas;
-public class Asteroid : Immovable
+public class Asteroid(XY initPos)
+ : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Asteroid)
{
public override bool IsRigid => true;
public override ShapeType Shape => ShapeType.Square;
- public Asteroid(XY initPos)
- : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Asteroid)
- {
- }
}
diff --git a/logic/GameClass/GameObj/Areas/Construction.cs b/logic/GameClass/GameObj/Areas/Construction.cs
index 8454c655..1da5e81b 100755
--- a/logic/GameClass/GameObj/Areas/Construction.cs
+++ b/logic/GameClass/GameObj/Areas/Construction.cs
@@ -3,10 +3,11 @@
namespace GameClass.GameObj.Areas;
-public class Construction : Immovable
+public class Construction(XY initPos)
+ : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Construction)
{
public AtomicLong TeamID { get; } = new(long.MaxValue);
- public LongInTheVariableRange HP { get; } = new LongInTheVariableRange(0, GameData.CommunityHP);
+ public LongInTheVariableRange HP { get; } = new(0, GameData.CommunityHP);
public override bool IsRigid => constructionType == ConstructionType.Community;
public override ShapeType Shape => ShapeType.Square;
private ConstructionType constructionType = ConstructionType.Null;
@@ -18,13 +19,13 @@ public bool Construct(int constructSpeed, ConstructionType constructionType, Shi
{
return false;
}
- if (this.constructionType != ConstructionType.Null && this.constructionType != constructionType && this.HP > 0)
+ if (this.constructionType != ConstructionType.Null && this.constructionType != constructionType && HP > 0)
{
return false;
}
- if (this.constructionType == ConstructionType.Null || this.HP == 0)
+ if (this.constructionType == ConstructionType.Null || HP == 0)
{
- this.TeamID.SetReturnOri(ship.TeamID);
+ TeamID.SetReturnOri(ship.TeamID);
this.constructionType = constructionType;
switch (constructionType)
{
@@ -45,12 +46,11 @@ public bool Construct(int constructSpeed, ConstructionType constructionType, Shi
}
public void BeAttacked(Bullet bullet)
{
- if (bullet!.Parent!.TeamID == this.TeamID)
+ if (bullet!.Parent!.TeamID != TeamID)
{
- return;
+ long subHP = bullet.AP;
+ HP.SubPositiveV(subHP);
}
- long subHP = bullet.AP;
- this.HP.SubPositiveV(subHP);
}
public void AddConstructNum(int add = 1)
{
@@ -60,8 +60,4 @@ public void SubConstructNum(int sub = 1)
{
ConstructNum.Sub(sub);
}
- public Construction(XY initPos)
- : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Construction)
- {
- }
}
diff --git a/logic/GameClass/GameObj/Areas/Home.cs b/logic/GameClass/GameObj/Areas/Home.cs
index b05f31dc..9dfb4093 100755
--- a/logic/GameClass/GameObj/Areas/Home.cs
+++ b/logic/GameClass/GameObj/Areas/Home.cs
@@ -14,10 +14,7 @@ public class Home(XY initPos, long id)
public void BeAttacked(Bullet bullet)
{
- if (bullet!.Parent!.TeamID == this.TeamID)
- {
- return;
- }
- this.HP.SubPositiveV(bullet.AP);
+ if (bullet!.Parent!.TeamID != TeamID)
+ HP.SubPositiveV(bullet.AP);
}
}
diff --git a/logic/GameClass/GameObj/Areas/NullArea.cs b/logic/GameClass/GameObj/Areas/NullArea.cs
index 342e6056..674b9f3f 100755
--- a/logic/GameClass/GameObj/Areas/NullArea.cs
+++ b/logic/GameClass/GameObj/Areas/NullArea.cs
@@ -2,12 +2,9 @@
namespace GameClass.GameObj.Areas;
-public class NullArea : Immovable
+public class NullArea(XY initPos)
+ : Immovable(initPos, int.MaxValue, GameObjType.Null)
{
public override bool IsRigid => false;
public override ShapeType Shape => ShapeType.Null;
- public NullArea(XY initPos)
- : base(initPos, int.MaxValue, GameObjType.Null)
- {
- }
}
diff --git a/logic/GameClass/GameObj/Areas/OutOfBoundBlock.cs b/logic/GameClass/GameObj/Areas/OutOfBoundBlock.cs
index 6d6d13a4..dfbcf758 100755
--- a/logic/GameClass/GameObj/Areas/OutOfBoundBlock.cs
+++ b/logic/GameClass/GameObj/Areas/OutOfBoundBlock.cs
@@ -6,12 +6,9 @@ namespace GameClass.GameObj.Areas;
///
/// 逻辑墙
///
-public class OutOfBoundBlock : Immovable, IOutOfBound
+public class OutOfBoundBlock(XY initPos)
+ : Immovable(initPos, int.MaxValue, GameObjType.OutOfBoundBlock), IOutOfBound
{
public override bool IsRigid => true;
public override ShapeType Shape => ShapeType.Square;
- public OutOfBoundBlock(XY initPos)
- : base(initPos, int.MaxValue, GameObjType.OutOfBoundBlock)
- {
- }
}
diff --git a/logic/GameClass/GameObj/Areas/Resource.cs b/logic/GameClass/GameObj/Areas/Resource.cs
index 76c657ed..4b0ad354 100755
--- a/logic/GameClass/GameObj/Areas/Resource.cs
+++ b/logic/GameClass/GameObj/Areas/Resource.cs
@@ -4,7 +4,8 @@
namespace GameClass.GameObj.Areas;
-public class Resource : Immovable
+public class Resource(XY initPos)
+ : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Resource)
{
public LongInTheVariableRange HP { get; } = new LongInTheVariableRange(GameData.ResourceHP);
public override bool IsRigid => true;
@@ -22,8 +23,4 @@ public void SubProduceNum(int sub = 1)
{
ProduceNum.Sub(sub);
}
- public Resource(XY initPos)
- : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Resource)
- {
- }
}
diff --git a/logic/GameClass/GameObj/Areas/Ruin.cs b/logic/GameClass/GameObj/Areas/Ruin.cs
index b3da5f49..fcb32017 100755
--- a/logic/GameClass/GameObj/Areas/Ruin.cs
+++ b/logic/GameClass/GameObj/Areas/Ruin.cs
@@ -1,14 +1,10 @@
using Preparation.Utility;
-using System;
namespace GameClass.GameObj.Areas;
-public class Ruin : Immovable
+public class Ruin(XY initPos)
+ : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Ruin)
{
public override bool IsRigid => true;
public override ShapeType Shape => ShapeType.Square;
- public Ruin(XY initPos)
- : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Ruin)
- {
- }
}
diff --git a/logic/GameClass/GameObj/Areas/Shadow.cs b/logic/GameClass/GameObj/Areas/Shadow.cs
index 3705a760..921d82db 100755
--- a/logic/GameClass/GameObj/Areas/Shadow.cs
+++ b/logic/GameClass/GameObj/Areas/Shadow.cs
@@ -3,12 +3,9 @@
namespace GameClass.GameObj.Areas;
-public class Shadow : Immovable
+public class Shadow(XY initPos)
+ : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Shadow)
{
public override bool IsRigid => false;
public override ShapeType Shape => ShapeType.Square;
- public Shadow(XY initPos)
- : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Shadow)
- {
- }
}
\ No newline at end of file
diff --git a/logic/GameClass/GameObj/Areas/Wormhole.cs b/logic/GameClass/GameObj/Areas/Wormhole.cs
index fdb68635..47153773 100755
--- a/logic/GameClass/GameObj/Areas/Wormhole.cs
+++ b/logic/GameClass/GameObj/Areas/Wormhole.cs
@@ -5,10 +5,11 @@
namespace GameClass.GameObj.Areas;
-public class Wormhole : Immovable, IWormhole
+public class Wormhole(XY initPos, List grids)
+ : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Wormhole), IWormhole
{
- public LongInTheVariableRange HP = new LongInTheVariableRange(GameData.WormholeHP);
- private readonly List grids = new();
+ public LongInTheVariableRange HP = new(GameData.WormholeHP);
+ private readonly List grids = grids;
public List Grids => grids;
public override bool IsRigid => HP > GameData.WormholeHP / 2;
public override ShapeType Shape => ShapeType.Square;
@@ -20,7 +21,7 @@ public bool Repair(int constructSpeed, Ship ship)
public void BeAttacked(Bullet bullet)
{
long subHP = bullet.AP;
- this.HP.SubPositiveV(subHP);
+ HP.SubPositiveV(subHP);
}
public void AddRepairNum(int add = 1)
{
@@ -30,9 +31,4 @@ public void SubRepairNum(int sub = 1)
{
RepairNum.Sub(sub);
}
- public Wormhole(XY initPos, List grids)
- : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Wormhole)
- {
- this.grids = grids;
- }
}
\ No newline at end of file
diff --git a/logic/GameClass/GameObj/BombedBullet.cs b/logic/GameClass/GameObj/BombedBullet.cs
index 8f3f3270..6e628038 100755
--- a/logic/GameClass/GameObj/BombedBullet.cs
+++ b/logic/GameClass/GameObj/BombedBullet.cs
@@ -3,20 +3,13 @@
namespace GameClass.GameObj
{
// 为方便界面组做子弹爆炸特效,现引入“爆炸中的子弹”,在每帧发送给界面组
- public sealed class BombedBullet : Immovable
+ public sealed class BombedBullet(Bullet bullet)
+ : Immovable(bullet.Position, bullet.Radius, GameObjType.BombedBullet)
{
public override ShapeType Shape => ShapeType.Circle;
public override bool IsRigid => false;
- public long MappingID { get; }
- public readonly Bullet bulletHasBombed;
- public readonly XY facingDirection;
-
- public BombedBullet(Bullet bullet) :
- base(bullet.Position, bullet.Radius, GameObjType.BombedBullet)
- {
- this.bulletHasBombed = bullet;
- this.MappingID = bullet.ID;
- this.facingDirection = bullet.FacingDirection;
- }
+ public long MappingID { get; } = bullet.ID;
+ public readonly Bullet bulletHasBombed = bullet;
+ public readonly XY facingDirection = bullet.FacingDirection;
}
}
diff --git a/logic/GameClass/GameObj/Bullet.cs b/logic/GameClass/GameObj/Bullet.cs
index b73c9815..05298313 100755
--- a/logic/GameClass/GameObj/Bullet.cs
+++ b/logic/GameClass/GameObj/Bullet.cs
@@ -35,8 +35,8 @@ public override bool IgnoreCollideExecutor(IGameObj targetObj)
public Bullet(Ship ship, int radius, XY Position) :
base(Position, radius, GameObjType.Bullet)
{
- this.CanMove.SetReturnOri(true);
- this.MoveSpeed.SetReturnOri(this.Speed);
- this.Parent = ship;
+ CanMove.SetReturnOri(true);
+ MoveSpeed.SetReturnOri(Speed);
+ Parent = ship;
}
}
diff --git a/logic/GameClass/GameObj/Bullets/Arc.cs b/logic/GameClass/GameObj/Bullets/Arc.cs
index 039e86be..96de7bf4 100755
--- a/logic/GameClass/GameObj/Bullets/Arc.cs
+++ b/logic/GameClass/GameObj/Bullets/Arc.cs
@@ -9,7 +9,7 @@ public Arc(Ship ship, XY pos, int radius = GameData.BulletRadius) :
base(ship, radius, pos)
{
Random random = new();
- this.AP.SetReturnOri(random.Next(GameData.ArcDamageMin, GameData.ArcDamageMax));
+ AP.SetReturnOri(random.Next(GameData.ArcDamageMin, GameData.ArcDamageMax));
}
public override double BulletBombRange => 0;
public override double AttackDistance => GameData.ArcRange;
diff --git a/logic/GameClass/GameObj/Bullets/Laser.cs b/logic/GameClass/GameObj/Bullets/Laser.cs
index 9df9a78c..e4551276 100755
--- a/logic/GameClass/GameObj/Bullets/Laser.cs
+++ b/logic/GameClass/GameObj/Bullets/Laser.cs
@@ -10,7 +10,7 @@ internal sealed class Laser : Bullet
public Laser(Ship ship, XY pos, int radius = GameData.BulletRadius) :
base(ship, radius, pos)
{
- this.AP.SetReturnOri(GameData.LaserDamage);
+ AP.SetReturnOri(GameData.LaserDamage);
}
public override double BulletBombRange => 0;
public override double AttackDistance => GameData.LaserRange;
diff --git a/logic/GameClass/GameObj/Bullets/Missile.cs b/logic/GameClass/GameObj/Bullets/Missile.cs
index 7302f893..2e4e0b84 100755
--- a/logic/GameClass/GameObj/Bullets/Missile.cs
+++ b/logic/GameClass/GameObj/Bullets/Missile.cs
@@ -8,7 +8,7 @@ internal sealed class Missile : Bullet
public Missile(Ship ship, XY pos, int radius = GameData.BulletRadius) :
base(ship, radius, pos)
{
- this.AP.SetReturnOri(GameData.MissileDamage);
+ AP.SetReturnOri(GameData.MissileDamage);
}
public override double BulletBombRange => GameData.MissileBombRange;
public override double AttackDistance => GameData.MissileRange;
diff --git a/logic/GameClass/GameObj/Bullets/NullBullet.cs b/logic/GameClass/GameObj/Bullets/NullBullet.cs
index f88bb1e5..12de9476 100755
--- a/logic/GameClass/GameObj/Bullets/NullBullet.cs
+++ b/logic/GameClass/GameObj/Bullets/NullBullet.cs
@@ -2,7 +2,8 @@
namespace GameClass.GameObj.Bullets;
-internal sealed class NullBullet(Ship ship, XY Position, int radius = GameData.BulletRadius) : Bullet(ship, radius, Position)
+internal sealed class NullBullet(Ship ship, XY Position, int radius = GameData.BulletRadius)
+ : Bullet(ship, radius, Position)
{
public override double BulletBombRange => 0;
public override double AttackDistance => 0;
diff --git a/logic/GameClass/GameObj/Bullets/Plasma.cs b/logic/GameClass/GameObj/Bullets/Plasma.cs
index deca2e1a..88d35ee7 100755
--- a/logic/GameClass/GameObj/Bullets/Plasma.cs
+++ b/logic/GameClass/GameObj/Bullets/Plasma.cs
@@ -7,7 +7,7 @@ internal sealed class Plasma : Bullet
public Plasma(Ship ship, XY pos, int radius = GameData.BulletRadius) :
base(ship, radius, pos)
{
- this.AP.SetReturnOri(GameData.PlasmaDamage);
+ AP.SetReturnOri(GameData.PlasmaDamage);
}
public override double BulletBombRange => 0;
public override double AttackDistance => GameData.PlasmaRange;
diff --git a/logic/GameClass/GameObj/Bullets/Shell.cs b/logic/GameClass/GameObj/Bullets/Shell.cs
index 1b01286e..40c88fc7 100755
--- a/logic/GameClass/GameObj/Bullets/Shell.cs
+++ b/logic/GameClass/GameObj/Bullets/Shell.cs
@@ -7,7 +7,7 @@ internal sealed class Shell : Bullet
public Shell(Ship ship, XY pos, int radius = GameData.BulletRadius) :
base(ship, radius, pos)
{
- this.AP.SetReturnOri(GameData.ShellDamage);
+ AP.SetReturnOri(GameData.ShellDamage);
}
public override double BulletBombRange => 0;
public override double AttackDistance => GameData.ShellRange;
diff --git a/logic/GameClass/GameObj/GameObj.cs b/logic/GameClass/GameObj/GameObj.cs
index 0adbdb35..eae58e58 100755
--- a/logic/GameClass/GameObj/GameObj.cs
+++ b/logic/GameClass/GameObj/GameObj.cs
@@ -7,37 +7,30 @@ namespace GameClass.GameObj
///
/// 一切游戏元素的总基类,与THUAI4不同,继承IMoveable接口(出于一切物体其实都是可运动的指导思想)——LHR
///
- public abstract class GameObj : IGameObj
+ public abstract class GameObj(XY initPos, int initRadius, GameObjType initType) : IGameObj
{
private readonly ReaderWriterLockSlim gameObjReaderWriterLock = new();
public ReaderWriterLockSlim GameObjReaderWriterLock => gameObjReaderWriterLock;
protected readonly object gameObjLock = new();
public object GameLock => gameObjLock;
- protected readonly XY birthPos;
- private readonly GameObjType type;
+ protected readonly XY birthPos = initPos;
+ private readonly GameObjType type = initType;
public GameObjType Type => type;
private static long currentMaxID = 0; // 目前游戏对象的最大ID
public const long invalidID = long.MaxValue; // 无效的ID
- public long ID { get; }
- protected XY position;
+ public long ID { get; } = Interlocked.Increment(ref currentMaxID);
+ protected XY position = initPos;
public abstract XY Position { get; }
public abstract bool IsRigid { get; }
public abstract ShapeType Shape { get; }
- private AtomicBool isRemoved = new(false);
+ private readonly AtomicBool isRemoved = new(false);
public AtomicBool IsRemoved { get => isRemoved; }
public virtual bool TryToRemove()
{
return IsRemoved.TrySet(true);
}
- public int Radius { get; }
+ public int Radius { get; } = initRadius;
public virtual bool IgnoreCollideExecutor(IGameObj targetObj) => false;
- public GameObj(XY initPos, int initRadius, GameObjType initType)
- {
- this.position = this.birthPos = initPos;
- this.Radius = initRadius;
- this.type = initType;
- ID = Interlocked.Increment(ref currentMaxID);
- }
}
}
diff --git a/logic/GameClass/GameObj/Immovable.cs b/logic/GameClass/GameObj/Immovable.cs
index 07211f59..314e7063 100755
--- a/logic/GameClass/GameObj/Immovable.cs
+++ b/logic/GameClass/GameObj/Immovable.cs
@@ -2,11 +2,8 @@
namespace GameClass.GameObj;
-public abstract class Immovable : GameObj
+public abstract class Immovable(XY initPos, int initRadius, GameObjType initType)
+ : GameObj(initPos, initRadius, initType)
{
public override XY Position => position;
- public Immovable(XY initPos, int initRadius, GameObjType initType)
- : base(initPos, initRadius, initType)
- {
- }
}
diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs
index 9460b26f..1561b28f 100755
--- a/logic/GameClass/GameObj/Map/Map.cs
+++ b/logic/GameClass/GameObj/Map/Map.cs
@@ -11,7 +11,7 @@ namespace GameClass.GameObj
{
public partial class Map : IMap
{
- private Dictionary> gameObjDict;
+ private readonly Dictionary> gameObjDict;
public Dictionary> GameObjDict => gameObjDict;
private readonly uint height;
public uint Height => height;
@@ -34,7 +34,8 @@ public PlaceType GetPlaceType(IGameObj obj)
{
try
{
- return protoGameMap[obj.Position.x / GameData.NumOfPosGridPerCell, obj.Position.y / GameData.NumOfPosGridPerCell];
+ var (x, y) = GameData.PosGridToCellXY(obj.Position);
+ return protoGameMap[x, y];
}
catch
{
@@ -45,7 +46,8 @@ public PlaceType GetPlaceType(XY pos)
{
try
{
- return protoGameMap[pos.x / GameData.NumOfPosGridPerCell, pos.y / GameData.NumOfPosGridPerCell];
+ var (x, y) = GameData.PosGridToCellXY(pos);
+ return protoGameMap[x, y];
}
catch
{
@@ -56,7 +58,10 @@ public PlaceType GetPlaceType(XY pos)
public bool IsOutOfBound(IGameObj obj)
{
- return obj.Position.x >= GameData.MapLength - obj.Radius || obj.Position.x <= obj.Radius || obj.Position.y >= GameData.MapLength - obj.Radius || obj.Position.y <= obj.Radius;
+ return obj.Position.x >= GameData.MapLength - obj.Radius
+ || obj.Position.x <= obj.Radius
+ || obj.Position.y >= GameData.MapLength - obj.Radius
+ || obj.Position.y <= obj.Radius;
}
public IOutOfBound GetOutOfBound(XY pos)
{
@@ -72,7 +77,7 @@ public IOutOfBound GetOutOfBound(XY pos)
return (Ship?)GameObjDict[GameObjType.Ship].Find(gameObj => (shipID == ((Ship)gameObj).ShipID));
}
- public bool WormholeInteract(Wormhole gameObj, XY Pos)
+ public static bool WormholeInteract(Wormhole gameObj, XY Pos)
{
foreach (XY xy in gameObj.Grids)
{
@@ -111,9 +116,11 @@ public bool CanSee(Ship ship, GameObj gameObj)
return false;
if (del.x > del.y)
{
+ var beginx = GameData.PosGridToCellX(pos1) + GameData.NumOfPosGridPerCell;
+ var endx = GameData.PosGridToCellX(pos2);
if (GetPlaceType(pos1) == PlaceType.Shadow && GetPlaceType(pos2) == PlaceType.Shadow)
{
- for (int x = GameData.PosGridToCellX(pos1) + GameData.NumOfPosGridPerCell; x < GameData.PosGridToCellX(pos2); x += GameData.NumOfPosGridPerCell)
+ for (int x = beginx; x < endx; x += GameData.NumOfPosGridPerCell)
{
if (GetPlaceType(pos1 + del * (x / del.x)) != PlaceType.Shadow)
return false;
@@ -121,7 +128,7 @@ public bool CanSee(Ship ship, GameObj gameObj)
}
else
{
- for (int x = GameData.PosGridToCellX(pos1) + GameData.NumOfPosGridPerCell; x < GameData.PosGridToCellX(pos2); x += GameData.NumOfPosGridPerCell)
+ for (int x = beginx; x < endx; x += GameData.NumOfPosGridPerCell)
{
if (GetPlaceType(pos1 + del * (x / del.x)) == PlaceType.Ruin)
return false;
@@ -130,9 +137,11 @@ public bool CanSee(Ship ship, GameObj gameObj)
}
else
{
+ var beginy = GameData.PosGridToCellY(pos1) + GameData.NumOfPosGridPerCell;
+ var endy = GameData.PosGridToCellY(pos2);
if (GetPlaceType(pos1) == PlaceType.Shadow && GetPlaceType(pos2) == PlaceType.Shadow)
{
- for (int y = GameData.PosGridToCellY(pos1) + GameData.NumOfPosGridPerCell; y < GameData.PosGridToCellY(pos2); y += GameData.NumOfPosGridPerCell)
+ for (int y = beginy; y < endy; y += GameData.NumOfPosGridPerCell)
{
if (GetPlaceType(pos1 + del * (y / del.y)) != PlaceType.Shadow)
return false;
@@ -140,7 +149,7 @@ public bool CanSee(Ship ship, GameObj gameObj)
}
else
{
- for (int y = GameData.PosGridToCellY(pos1) + GameData.NumOfPosGridPerCell; y < GameData.PosGridToCellY(pos2); y += GameData.NumOfPosGridPerCell)
+ for (int y = beginy; y < endy; y += GameData.NumOfPosGridPerCell)
{
if (GetPlaceType(pos1 + del * (y / del.y)) == PlaceType.Ruin)
return false;
@@ -174,7 +183,7 @@ public void Add(IGameObj gameObj)
}
public Map(MapStruct mapResource)
{
- gameObjDict = new Dictionary>();
+ gameObjDict = [];
foreach (GameObjType idx in Enum.GetValues(typeof(GameObjType)))
{
if (idx != GameObjType.Null)
diff --git a/logic/GameClass/GameObj/Map/MapGameTimer.cs b/logic/GameClass/GameObj/Map/MapGameTimer.cs
index 1adc30f6..eae1561c 100755
--- a/logic/GameClass/GameObj/Map/MapGameTimer.cs
+++ b/logic/GameClass/GameObj/Map/MapGameTimer.cs
@@ -1,6 +1,5 @@
using System;
using System.Threading;
-using Preparation.Interface;
using Preparation.Utility;
using ITimer = Preparation.Interface.ITimer;
@@ -17,7 +16,7 @@ public class GameTimer : ITimer
private long startTime;
public int nowTime() => (int)(Environment.TickCount64 - startTime);
- private AtomicBool isGaming = new(false);
+ private readonly AtomicBool isGaming = new(false);
public AtomicBool IsGaming => isGaming;
public bool StartGame(int timeInMilliseconds)
diff --git a/logic/GameClass/GameObj/Movable.cs b/logic/GameClass/GameObj/Movable.cs
index 0a157bfd..1b9922c8 100755
--- a/logic/GameClass/GameObj/Movable.cs
+++ b/logic/GameClass/GameObj/Movable.cs
@@ -4,7 +4,8 @@
namespace GameClass.GameObj
{
- public abstract class Movable : GameObj, IMovable
+ public abstract class Movable(XY initPos, int initRadius, GameObjType initType)
+ : GameObj(initPos, initRadius, initType), IMovable
{
protected readonly object actionLock = new();
///
@@ -92,10 +93,10 @@ public void ReSetPos(XY position)
this.position = position;
}
}
- private AtomicBool canMove = new(false);
+ private readonly AtomicBool canMove = new(false);
public AtomicBool CanMove { get => canMove; }
public bool IsAvailableForMove => !IsMoving && CanMove && !IsRemoved; // 是否能接收移动指令
- private AtomicInt moveSpeed = new(0);
+ private readonly AtomicInt moveSpeed = new(0);
///
/// 移动速度
///
@@ -105,23 +106,21 @@ public void ReSetPos(XY position)
/// 原初移动速度
///
public int OrgMoveSpeed => orgMoveSpeed;
- /* ///
- /// 复活时数据重置
- ///
- public virtual void Reset(PlaceType place)
- {
- lock (gameObjLock)
- {
- this.FacingDirection = new XY(1, 0);
- isMoving = false;
- CanMove = false;
- IsRemoved = true;
- this.Position = birthPos;
- this.Place= place;
- }
- }*/
- public Movable(XY initPos, int initRadius, GameObjType initType) : base(initPos, initRadius, initType)
+
+ /*///
+ /// 复活时数据重置
+ ///
+ public virtual void Reset(PlaceType place)
{
- }
+ lock (gameObjLock)
+ {
+ this.FacingDirection = new XY(1, 0);
+ isMoving = false;
+ CanMove = false;
+ IsRemoved = true;
+ this.Position = birthPos;
+ this.Place = place;
+ }
+ }*/
}
}
diff --git a/logic/GameClass/GameObj/ObjOfShip.cs b/logic/GameClass/GameObj/ObjOfShip.cs
index 83d0c5f5..39978a2f 100755
--- a/logic/GameClass/GameObj/ObjOfShip.cs
+++ b/logic/GameClass/GameObj/ObjOfShip.cs
@@ -7,7 +7,8 @@ namespace GameClass.GameObj
///
/// 所有物,具有主人(Parent)(特定玩家)属性的对象
///
- public abstract class ObjOfShip : Movable, IObjOfShip
+ public abstract class ObjOfShip(XY initPos, int initRadius, GameObjType initType)
+ : Movable(initPos, initRadius, initType), IObjOfShip
{
public object ObjOfShipLock { get; } = new();
private IShip? parent = null;
@@ -24,9 +25,5 @@ public IShip? Parent
parent = value;
}
}
- public ObjOfShip(XY initPos, int initRadius, GameObjType initType) :
- base(initPos, initRadius, initType)
- {
- }
}
}
diff --git a/logic/GameEngine/CollisionChecker.cs b/logic/GameEngine/CollisionChecker.cs
index d8dddcbb..7c1e2010 100755
--- a/logic/GameEngine/CollisionChecker.cs
+++ b/logic/GameEngine/CollisionChecker.cs
@@ -1,22 +1,18 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
using Preparation.Interface;
using Preparation.Utility;
namespace GameEngine
{
- internal class CollisionChecker
+ internal class CollisionChecker(IMap gameMap)
{
public IGameObj? CheckCollision(IMovable obj, XY Pos)
{
// 在列表中检查碰撞
- Func, IGameObj?> CheckCollisionInList =
- (LockedClassList lst) =>
- {
- return lst.Find(listObj => obj.WillCollideWith(listObj, Pos));
- };
+ IGameObj? CheckCollisionInList(LockedClassList lst)
+ {
+ return lst.Find(listObj => obj.WillCollideWith(listObj, Pos));
+ }
IGameObj? collisionObj;
foreach (var list in lists)
@@ -117,67 +113,65 @@ public double FindMax(IMovable obj, XY moveVec)
// 如果再走一步发生碰撞
if (obj.WillCollideWith(listObj, nextPos))
{
+ switch (listObj.Shape) // 默认obj为圆形
{
- switch (listObj.Shape) // 默认obj为圆形
- {
- case ShapeType.Circle:
- {
- // 计算两者之间的距离
- double mod = XY.DistanceFloor3(listObj.Position, obj.Position);
- int orgDeltaX = listObj.Position.x - obj.Position.x;
- int orgDeltaY = listObj.Position.y - obj.Position.y;
+ case ShapeType.Circle:
+ {
+ // 计算两者之间的距离
+ double mod = XY.DistanceFloor3(listObj.Position, obj.Position);
+ int orgDeltaX = listObj.Position.x - obj.Position.x;
+ int orgDeltaY = listObj.Position.y - obj.Position.y;
- if (mod < listObj.Radius + obj.Radius) // 如果两者已经重叠
+ if (mod < listObj.Radius + obj.Radius) // 如果两者已经重叠
+ {
+ tmpMax = 0;
+ }
+ else
+ {
+ double tmp = mod - obj.Radius - listObj.Radius;
+ // 计算能走的最长距离,好像这么算有一点误差?
+ tmp = (int)(tmp * 1000 / Math.Cos(Math.Atan2(orgDeltaY, orgDeltaX) - moveVec.Angle()));
+ if (tmp < 0 || tmp > uint.MaxValue || double.IsNaN(tmp))
{
- tmpMax = 0;
+ tmpMax = uint.MaxValue;
}
else
- {
- double tmp = mod - obj.Radius - listObj.Radius;
- // 计算能走的最长距离,好像这么算有一点误差?
- tmp = ((int)(tmp * 1000 / Math.Cos(Math.Atan2(orgDeltaY, orgDeltaX) - moveVec.Angle())));
- if (tmp < 0 || tmp > uint.MaxValue || double.IsNaN(tmp))
- {
- tmpMax = uint.MaxValue;
- }
- else
- tmpMax = tmp / 1000.0;
- }
- break;
+ tmpMax = tmp / 1000.0;
}
- case ShapeType.Square:
+ break;
+ }
+ case ShapeType.Square:
+ {
+ // if (obj.WillCollideWith(listObj, obj.Position))
+ // tmpMax = 0;
+ // else tmpMax = MaxMoveToSquare(obj, listObj);
+ // break;
+ if (obj.WillCollideWith(listObj, obj.Position))
+ tmpMax = 0;
+ else
{
- // if (obj.WillCollideWith(listObj, obj.Position))
- // tmpMax = 0;
- // else tmpMax = MaxMoveToSquare(obj, listObj);
- // break;
- if (obj.WillCollideWith(listObj, obj.Position))
- tmpMax = 0;
- else
+ // 二分查找最大可能移动距离
+ int left = 0, right = (int)moveVec.Length();
+ while (left < right - 1)
{
- // 二分查找最大可能移动距离
- int left = 0, right = (int)moveVec.Length();
- while (left < right - 1)
+ int mid = (right - left) / 2 + left;
+ if (obj.WillCollideWith(listObj, obj.Position + new XY(moveVec, mid)))
{
- int mid = (right - left) / 2 + left;
- if (obj.WillCollideWith(listObj, obj.Position + new XY(moveVec, mid)))
- {
- right = mid;
- }
- else
- left = mid;
+ right = mid;
}
- tmpMax = (uint)left;
+ else
+ left = mid;
}
- break;
+ tmpMax = (uint)left;
}
- default:
- tmpMax = uint.MaxValue;
break;
- }
- if (tmpMax < maxDistance)
- maxDistance = tmpMax;
+ }
+ default:
+ tmpMax = uint.MaxValue;
+ break;
}
+ if (tmpMax < maxDistance)
+ maxDistance = tmpMax;
}
}
);
@@ -185,13 +179,7 @@ public double FindMax(IMovable obj, XY moveVec)
return maxDistance;
}
- readonly IMap gameMap;
- private readonly LockedClassList[] lists;
-
- public CollisionChecker(IMap gameMap)
- {
- this.gameMap = gameMap;
- lists = gameMap.GameObjDict.Values.ToArray();
- }
+ readonly IMap gameMap = gameMap;
+ private readonly LockedClassList[] lists = [.. gameMap.GameObjDict.Values];
}
}
diff --git a/logic/GameEngine/MoveEngine.cs b/logic/GameEngine/MoveEngine.cs
index 7b4b2ebd..ba227413 100755
--- a/logic/GameEngine/MoveEngine.cs
+++ b/logic/GameEngine/MoveEngine.cs
@@ -7,7 +7,23 @@
namespace GameEngine
{
- public class MoveEngine
+ ///
+ /// Constrctor
+ ///
+ /// 游戏地图
+ ///
+ /// 发生碰撞时要做的事情
+ /// - 第一个参数为移动的物体
+ /// - 第二个参数为撞到的物体
+ /// - 第三个参数为移动的位移向量
+ /// 返回值见AfterCollision的定义
+ ///
+ /// 结束碰撞时要做的事情
+ public class MoveEngine(
+ IMap gameMap,
+ Func OnCollision,
+ Action EndMove
+ )
{
///
/// 碰撞结束后要做的事情
@@ -19,33 +35,16 @@ public enum AfterCollision
Destroyed = 2 // 物体已经毁坏
}
- private readonly ITimer gameTimer;
- private readonly Action EndMove;
+ private readonly ITimer gameTimer = gameMap.Timer;
+ private readonly Action EndMove = EndMove;
public IGameObj? CheckCollision(IMovable obj, XY Pos)
{
return collisionChecker.CheckCollision(obj, Pos);
}
- private readonly CollisionChecker collisionChecker;
- private readonly Func OnCollision;
- ///
- /// Constrctor
- ///
- /// 游戏地图
- /// 发生碰撞时要做的事情,第一个参数为移动的物体,第二个参数为撞到的物体,第三个参数为移动的位移向量,返回值见AfterCollision的定义
- /// 结束碰撞时要做的事情
- public MoveEngine(
- IMap gameMap,
- Func OnCollision,
- Action EndMove
- )
- {
- this.gameTimer = gameMap.Timer;
- this.EndMove = EndMove;
- this.OnCollision = OnCollision;
- this.collisionChecker = new CollisionChecker(gameMap);
- }
+ private readonly CollisionChecker collisionChecker = new(gameMap);
+ private readonly Func OnCollision = OnCollision;
///
/// 在无碰撞的前提下行走最远的距离
@@ -62,7 +61,7 @@ private bool MoveMax(IMovable obj, XY moveVec, long stateNum)
// 尝试滑动
IGameObj? collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, moveVec);
XY slideVec = new(0, 0);
- switch (collisionObj.Shape)
+ switch (collisionObj?.Shape)
{
case ShapeType.Circle:
XY connectVec = collisionObj.Position - obj.Position;
@@ -81,6 +80,8 @@ private bool MoveMax(IMovable obj, XY moveVec, long stateNum)
slideVec = new XY(moveVec.x * Math.Sign(collisionObj.Position.x - obj.Position.x), 0);
}
break;
+ default:
+ break;
}
double slideLen = collisionChecker.FindMax(obj, slideVec);
slideLen = Math.Min(slideLen, slideVec.Length());
@@ -110,7 +111,7 @@ private bool LoopDo(IMovable obj, double direction, ref double deltaLen, long st
flag = true;
break;
case AfterCollision.Destroyed:
- Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
+ Debugger.Output(obj, $"collide with {collisionObj} and has been removed from the game.");
return false;
case AfterCollision.MoveMax:
if (!MoveMax(obj, res, stateNum)) return false;
@@ -141,7 +142,7 @@ public void MoveObj(IMovable obj, int moveTime, double direction, long stateNum)
{
double moveVecLength = 0.0;
XY res = new(direction, moveVecLength);
- double deltaLen = (double)0.0; // 转向,并用deltaLen存储行走的误差
+ double deltaLen = 0.0; // 转向,并用deltaLen存储行走的误差
IGameObj? collisionObj = null;
bool isEnded = false;
@@ -159,7 +160,7 @@ public void MoveObj(IMovable obj, int moveTime, double direction, long stateNum)
flag = true;
break;
case AfterCollision.Destroyed:
- Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
+ Debugger.Output(obj, $"collide with {collisionObj} and has been removed from the game.");
isEnded = true;
break;
case AfterCollision.MoveMax:
@@ -200,7 +201,6 @@ public void MoveObj(IMovable obj, int moveTime, double direction, long stateNum)
{
if (b)
Console.WriteLine("Fatal Error: The computer runs so slow that the object cannot finish moving during this time!!!!!!");
-
#if DEBUG
else
{
@@ -242,7 +242,7 @@ public void MoveObj(IMovable obj, int moveTime, double direction, long stateNum)
flag = true;
break;
case AfterCollision.Destroyed:
- Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
+ Debugger.Output(obj, $"collide with {collisionObj} and has been removed from the game.");
isEnded = true;
break;
case AfterCollision.MoveMax:
diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs
index 6d9898e1..4604da94 100755
--- a/logic/Gaming/AttackManager.cs
+++ b/logic/Gaming/AttackManager.cs
@@ -7,6 +7,7 @@
using Preparation.Utility;
using Preparation.Interface;
using Timothy.FrameRateTask;
+using System.Linq;
namespace Gaming
{
@@ -101,7 +102,7 @@ private void BulletBomb(Bullet bullet, GameObj? objBeingShot)
beAttackedList.AddRange(gameMap.GameObjDict[kvp.Key].FindAll(gameObj => bullet.CanAttack((GameObj)gameObj)));
}
}
- foreach (GameObj beAttackedObj in beAttackedList)
+ foreach (GameObj beAttackedObj in beAttackedList.Cast())
{
BombObj(bullet, beAttackedObj);
}
diff --git a/logic/Preparation/Utility/Debugger.cs b/logic/Preparation/Utility/Debugger.cs
index 8627e316..94ca944b 100755
--- a/logic/Preparation/Utility/Debugger.cs
+++ b/logic/Preparation/Utility/Debugger.cs
@@ -7,7 +7,7 @@ public class Debugger
static public void Output(object current, string str)
{
#if DEBUG
- Console.WriteLine(current.GetType() + " " + current.ToString() + " " + str);
+ Console.WriteLine($"{current.GetType()} {current} {str}");
#endif
}
static public void Output(string str)
diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs
index c97abb4c..12141935 100755
--- a/logic/Preparation/Utility/GameData.cs
+++ b/logic/Preparation/Utility/GameData.cs
@@ -26,10 +26,7 @@ public static class GameData
public const int InitialMoney = 50; // 初始金钱
- public static bool IsGameObjMap(GameObjType gameObjType)
- {
- return (uint)gameObjType > 3;
- }
+ public static bool IsGameObjMap(GameObjType gameObjType) => (uint)gameObjType > 3;
public static bool NeedCopy(GameObjType gameObjType)
{
return gameObjType != GameObjType.Null &&
@@ -39,39 +36,32 @@ public static bool NeedCopy(GameObjType gameObjType)
gameObjType != GameObjType.OutOfBoundBlock;
}
public static XY GetCellCenterPos(int x, int y) // 求格子的中心坐标
- {
- XY ret = new(x * NumOfPosGridPerCell + NumOfPosGridPerCell / 2, y * NumOfPosGridPerCell + NumOfPosGridPerCell / 2);
- return ret;
- }
+ => new(x * NumOfPosGridPerCell + NumOfPosGridPerCell / 2,
+ y * NumOfPosGridPerCell + NumOfPosGridPerCell / 2);
+
public static int PosGridToCellX(XY pos) // 求坐标所在的格子的x坐标
- {
- return pos.x / NumOfPosGridPerCell;
- }
+ => pos.x / NumOfPosGridPerCell;
public static int PosGridToCellY(XY pos) // 求坐标所在的格子的y坐标
- {
- return pos.y / NumOfPosGridPerCell;
- }
- public static XY PosGridToCellXY(XY pos) // 求坐标所在的格子的xy坐标
- {
- return new XY(pos.x / NumOfPosGridPerCell, pos.y / NumOfPosGridPerCell);
- }
- public static bool IsInTheSameCell(XY pos1, XY pos2)
- {
- return PosGridToCellX(pos1) == PosGridToCellX(pos2) && PosGridToCellY(pos1) == PosGridToCellY(pos2);
- }
+ => pos.y / NumOfPosGridPerCell;
+ public static CellXY PosGridToCellXY(XY pos) // 求坐标所在的格子的xy坐标
+ => new(PosGridToCellX(pos), PosGridToCellY(pos));
+
+ public static bool IsInTheSameCell(XY pos1, XY pos2) => PosGridToCellXY(pos1) == PosGridToCellXY(pos2);
public static bool PartInTheSameCell(XY pos1, XY pos2)
{
return Math.Abs((pos1 - pos2).x) < ShipRadius + (NumOfPosGridPerCell / 2)
- && Math.Abs((pos1 - pos2).y) < ShipRadius + (NumOfPosGridPerCell / 2);
+ && Math.Abs((pos1 - pos2).y) < ShipRadius + (NumOfPosGridPerCell / 2);
}
public static bool ApproachToInteract(XY pos1, XY pos2)
{
- return Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2)) <= 1 && Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2)) <= 1;
+ return Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2)) <= 1
+ && Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2)) <= 1;
}
public static bool ApproachToInteractInACross(XY pos1, XY pos2)
{
if (pos1 == pos2) return false;
- return (Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2)) + Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2))) <= 1;
+ return (Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2))
+ + Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2))) <= 1;
}
public const int ShipRadius = 400;
@@ -175,18 +165,9 @@ public static bool ApproachToInteractInACross(XY pos1, XY pos2)
public const int ScoreProducer2PerSecond = 7;
public const int ScoreProducer3PerSecond = 10;
public const int ScoreConstructionDamaged = 200;
- public static int ScoreShipKilled(int totalScore)
- {
- return totalScore / 5;
- }
- public static int ScoreShipRecovered(int totalRecovery)
- {
- return totalRecovery * 6 / 5;
- }
- public static int ScoreShipRecycled(int remainingHP)
- {
- return remainingHP / 2;
- }
+ public static int ScoreShipKilled(int totalScore) => totalScore / 5;
+ public static int ScoreShipRecovered(int totalRecovery) => totalRecovery * 6 / 5;
+ public static int ScoreShipRecycled(int remainingHP) => remainingHP / 2;
public const int Constructor1Speed = 500;
public const int Constructor2Speed = 750;
diff --git a/logic/Preparation/Utility/Logger.cs b/logic/Preparation/Utility/Logger.cs
index 27cd453f..84c1e976 100755
--- a/logic/Preparation/Utility/Logger.cs
+++ b/logic/Preparation/Utility/Logger.cs
@@ -8,13 +8,13 @@ public class Logger
static public void Writelog(object current, string str)
{
string path = "log.txt";
- string log = string.Format("[{0}] {1} {2} {3}", DateTime.Now, current.GetType(), current.ToString(), str);
+ string log = $"[{DateTime.Now}] {current.GetType()} {current} {str}";
File.AppendAllText(path, log + Environment.NewLine);
}
static public void Writelog(string str)
{
string path = "log.txt";
- string log = string.Format("[{0}] {1}", DateTime.Now, str);
+ string log = $"[{DateTime.Now}] {str}";
File.AppendAllText(path, log + Environment.NewLine);
}
}
diff --git a/logic/Preparation/Utility/SafeValue/Atomic.cs b/logic/Preparation/Utility/SafeValue/Atomic.cs
index f0b2a680..6a20f2d1 100755
--- a/logic/Preparation/Utility/SafeValue/Atomic.cs
+++ b/logic/Preparation/Utility/SafeValue/Atomic.cs
@@ -8,13 +8,10 @@ public abstract class Atomic
{
}
- public class AtomicInt : Atomic
+ public class AtomicInt(int x) : Atomic
{
- protected int v;
- public AtomicInt(int x)
- {
- v = x;
- }
+ protected int v = x;
+
public override string ToString() => Interlocked.CompareExchange(ref v, -1, -1).ToString();
public int Get() => Interlocked.CompareExchange(ref v, -1, -1);
public static implicit operator int(AtomicInt aint) => Interlocked.CompareExchange(ref aint.v, -1, -1);
@@ -42,15 +39,11 @@ public AtomicInt(int x)
/// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed(取整)。
/// 注意:AtomicIntOnlyAddScore本身为AtomicInt,提供的Score可能构成环而死锁。
///
- public class AtomicIntOnlyAddScore : AtomicInt
+ public class AtomicIntOnlyAddScore(int x, double speed = 1.0) : AtomicInt(x)
{
- public AtomicInt Score { get; set; }
- public AtomicDouble speed;
- public AtomicIntOnlyAddScore(int x, double speed = 1.0) : base(x)
- {
- this.speed = new(speed);
- this.Score = new(0);
- }
+ public AtomicInt Score { get; set; } = new(0);
+ public AtomicDouble speed = new(speed);
+
public void SetScore(AtomicInt score) => Score = score;
/// 返回操作前的值
public override int SetReturnOri(int value)
@@ -127,15 +120,11 @@ public int CompareExReturnOriNotAddScore(int newV, int compareTo)
/// 可(在构造时)使用SetScore以设定AtomicLong类的Score(取整)
/// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。
///
- public class AtomicIntOnlyAddLongScore : AtomicInt
+ public class AtomicIntOnlyAddLongScore(int x, double speed = 1.0) : AtomicInt(x)
{
- public AtomicLong Score { get; set; }
- public AtomicDouble speed;
- public AtomicIntOnlyAddLongScore(int x, double speed = 1.0) : base(x)
- {
- this.Score = new(0);
- this.speed = new(speed);
- }
+ public AtomicLong Score { get; set; } = new(0);
+ public AtomicDouble speed = new(speed);
+
public void SetScore(AtomicLong score) => Score = score;
/// 返回操作前的值
public override int SetReturnOri(int value)
@@ -206,15 +195,11 @@ public int CompareExReturnOriNotAddScore(int newV, int compareTo)
/// 在发生变化时,自动给Score加上变化的差乘以speed取整。
/// 注意:AtomicIntChangeAffectScore本身为AtomicInt,提供的Score可能构成环而死锁。
///
- public class AtomicIntChangeAffectScore : AtomicInt
+ public class AtomicIntChangeAffectScore(int x, double speed = 1.0) : AtomicInt(x)
{
- public AtomicInt Score { get; set; }
- public AtomicDouble speed;
- public AtomicIntChangeAffectScore(int x, double speed = 1.0) : base(x)
- {
- this.Score = new(0);
- this.speed = new(speed);
- }
+ public AtomicInt Score { get; set; } = new(0);
+ public AtomicDouble speed = new(speed);
+
public void SetScore(AtomicInt score) => Score = score;
/// 返回操作前的值
public override int SetReturnOri(int value)
@@ -294,13 +279,10 @@ public int CompareExReturnOriNotAddScore(int newV, int compareTo)
}
}
- public class AtomicLong : Atomic
+ public class AtomicLong(long x) : Atomic
{
- protected long v;
- public AtomicLong(long x)
- {
- v = x;
- }
+ protected long v = x;
+
public override string ToString() => Interlocked.CompareExchange(ref v, -1, -1).ToString();
public long Get() => Interlocked.CompareExchange(ref v, -1, -1);
public static implicit operator long(AtomicLong along) => Interlocked.CompareExchange(ref along.v, -1, -1);
@@ -328,15 +310,11 @@ public AtomicLong(long x)
/// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed取整。
/// 注意:AtomicLongOnlyAddScore本身为AtomicLong,提供的Score可能构成环而死锁。
///
- public class AtomicLongOnlyAddScore : AtomicLong
+ public class AtomicLongOnlyAddScore(long x, double speed = 1.0) : AtomicLong(x)
{
- public AtomicLong Score { get; set; }
- public AtomicDouble speed;
- public AtomicLongOnlyAddScore(long x, double speed = 1.0) : base(x)
- {
- this.Score = new(0);
- this.speed = new(speed);
- }
+ public AtomicLong Score { get; set; } = new(0);
+ public AtomicDouble speed = new(speed);
+
public void SetScore(AtomicLong score) => Score = score;
/// 返回操作前的值
@@ -402,13 +380,10 @@ public long CompareExReturnOriNotAddScore(long newV, long compareTo)
}
}
- public class AtomicDouble : Atomic
+ public class AtomicDouble(double x) : Atomic
{
- private double v;
- public AtomicDouble(double x)
- {
- v = x;
- }
+ private double v = x;
+
public override string ToString() => Interlocked.CompareExchange(ref v, -2.0, -2.0).ToString();
public double Get() => Interlocked.CompareExchange(ref v, -2.0, -2.0);
public static implicit operator double(AtomicDouble adouble) => Interlocked.CompareExchange(ref adouble.v, -2.0, -2.0);
@@ -418,13 +393,10 @@ public AtomicDouble(double x)
public double CompareExReturnOri(double newV, double compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
}
- public class AtomicBool : Atomic
+ public class AtomicBool(bool x) : Atomic
{
- private int v;//v&1==0为false,v&1==1为true
- public AtomicBool(bool x)
- {
- v = x ? 1 : 0;
- }
+ private int v = x ? 1 : 0;//v&1==0为false,v&1==1为true
+
public override string ToString() => ((Interlocked.CompareExchange(ref v, -2, -2) & 1) == 0) ? "false" : "true";
public bool Get() => ((Interlocked.CompareExchange(ref v, -2, -2) & 1) == 1);
public static implicit operator bool(AtomicBool abool) => abool.Get();
diff --git a/logic/Preparation/Utility/Tools/XY.cs b/logic/Preparation/Utility/Tools/XY.cs
index 6495839b..5a2a1e89 100644
--- a/logic/Preparation/Utility/Tools/XY.cs
+++ b/logic/Preparation/Utility/Tools/XY.cs
@@ -2,10 +2,12 @@
namespace Preparation.Utility;
-public class XY
+public readonly struct XY
{
- public int x;
- public int y;
+ public readonly int x;
+ public readonly int y;
+
+ #region ctor
public XY(int x, int y)
{
this.x = x;
@@ -29,89 +31,139 @@ public XY(XY Direction, double length)
this.y = (int)(length * Math.Sin(Direction.Angle()));
}
}
- public override string ToString()
- {
- return "(" + x.ToString() + "," + y.ToString() + ")";
- }
- public static int operator *(XY v1, XY v2)
- {
- return (v1.x * v2.x) + (v1.y * v2.y);
- }
- public static XY operator *(int a, XY v2)
+ #endregion
+
+ public override string ToString() => $"({x}, {y})";
+ /// 数量积
+ public static int operator *(XY v1, XY v2) => (v1.x * v2.x) + (v1.y * v2.y);
+ /// 左数乘
+ public static XY operator *(int a, XY v2) => new(a * v2.x, a * v2.y);
+ /// 右数乘
+ public static XY operator *(XY v2, int a) => new(a * v2.x, a * v2.y);
+ public static XY operator +(XY v1, XY v2) => new(v1.x + v2.x, v1.y + v2.y);
+ public static XY operator -(XY v1, XY v2) => new(v1.x - v2.x, v1.y - v2.y);
+ public static bool operator ==(XY v1, XY v2) => (v1.x == v2.x) && (v1.y == v2.y);
+ public static bool operator !=(XY v1, XY v2) => (v1.x != v2.x) || (v1.y != v2.y);
+
+ #region Distance
+ public static double DistanceFloor3(XY p1, XY p2)
{
- return new XY(a * v2.x, a * v2.y);
+ long c = (((long)(p1.x - p2.x) * (p1.x - p2.x)) + ((long)(p1.y - p2.y) * (p1.y - p2.y))) * 1000000;
+ long t = c / 2 + 1;
+ while (t * t > c || (t + 1) * (t + 1) <= c)
+ t = (c / t + t) / 2;
+ return t / 1000.0;
}
- public static XY operator *(XY v2, int a)
+ public static double DistanceCeil3(XY p1, XY p2)
{
- return new XY(a * v2.x, a * v2.y);
+ long c = (((long)(p1.x - p2.x) * (p1.x - p2.x)) + ((long)(p1.y - p2.y) * (p1.y - p2.y))) * 1000000;
+ long t = c / 2 + 1;
+ while (t * t > c || (t + 1) * (t + 1) <= c)
+ t = (c / t + t) / 2;
+ if (t * t == c) return t / 1000.0;
+ else return (t + 1) / 1000.0;
}
- public static XY operator +(XY v1, XY v2)
+ #endregion
+
+ public double Length() => Math.Sqrt(((long)x * x) + ((long)y * y));
+ public double Angle() => Math.Atan2(y, x);
+
+ ///
+ /// 逆时针旋转90°
+ ///
+ public XY Perpendicular() => new(-y, x);
+
+ public override bool Equals(object? obj) => (obj is not null) && (obj is XY xy) && (this == xy);
+ public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode();
+
+ ///
+ /// 解包
+ ///
+ public void Deconstruct(out int x, out int y)
{
- return new XY(v1.x + v2.x, v1.y + v2.y);
+ x = this.x; y = this.y;
}
- public static XY operator -(XY v1, XY v2)
+}
+
+public readonly struct CellXY
+{
+ public readonly int x;
+ public readonly int y;
+
+ #region ctor
+ public CellXY(int x, int y)
{
- return new XY(v1.x - v2.x, v1.y - v2.y);
+ this.x = x;
+ this.y = y;
}
- public static bool operator ==(XY v1, XY v2)
+ public CellXY(double angle, double length)
{
- return v1.x == v2.x && v1.y == v2.y;
+ this.x = (int)(length * Math.Cos(angle));
+ this.y = (int)(length * Math.Sin(angle));
}
- public static bool operator !=(XY v1, XY v2)
+ public CellXY(XY Direction, double length)
{
- return v1.x != v2.x || v1.y != v2.y;
+ if (Direction.x == 0 && Direction.y == 0)
+ {
+ this.x = 0;
+ this.y = 0;
+ }
+ else
+ {
+ this.x = (int)(length * Math.Cos(Direction.Angle()));
+ this.y = (int)(length * Math.Sin(Direction.Angle()));
+ }
}
+ #endregion
- public static double DistanceFloor3(XY p1, XY p2)
+ public override string ToString() => $"({x}, {y})";
+ /// 数量积
+ public static int operator *(CellXY v1, CellXY v2) => (v1.x * v2.x) + (v1.y * v2.y);
+ /// 左数乘
+ public static CellXY operator *(int a, CellXY v2) => new(a * v2.x, a * v2.y);
+ /// 右数乘
+ public static CellXY operator *(CellXY v2, int a) => new(a * v2.x, a * v2.y);
+ public static CellXY operator +(CellXY v1, CellXY v2) => new(v1.x + v2.x, v1.y + v2.y);
+ public static CellXY operator -(CellXY v1, CellXY v2) => new(v1.x - v2.x, v1.y - v2.y);
+ public static bool operator ==(CellXY v1, CellXY v2) => (v1.x == v2.x) && (v1.y == v2.y);
+ public static bool operator !=(CellXY v1, CellXY v2) => (v1.x != v2.x) || (v1.y != v2.y);
+
+ #region Distance
+ public static double DistanceFloor3(CellXY p1, CellXY p2)
{
long c = (((long)(p1.x - p2.x) * (p1.x - p2.x)) + ((long)(p1.y - p2.y) * (p1.y - p2.y))) * 1000000;
long t = c / 2 + 1;
while (t * t > c || (t + 1) * (t + 1) <= c)
t = (c / t + t) / 2;
- return (double)t / 1000.0;
+ return t / 1000.0;
}
- public static double DistanceCeil3(XY p1, XY p2)
+ public static double DistanceCeil3(CellXY p1, CellXY p2)
{
long c = (((long)(p1.x - p2.x) * (p1.x - p2.x)) + ((long)(p1.y - p2.y) * (p1.y - p2.y))) * 1000000;
long t = c / 2 + 1;
while (t * t > c || (t + 1) * (t + 1) <= c)
t = (c / t + t) / 2;
- if (t * t == c) return (double)t / 1000.0;
- else return (double)(t + 1) / 1000.0;
- }
- public double Length()
- {
- return Math.Sqrt(((long)x * x) + ((long)y * y));
- }
- public double Angle()
- {
- return Math.Atan2(y, x);
+ if (t * t == c) return t / 1000.0;
+ else return (t + 1) / 1000.0;
}
+ #endregion
+
+ public double Length() => Math.Sqrt(((long)x * x) + ((long)y * y));
+ public double Angle() => Math.Atan2(y, x);
///
/// 逆时针旋转90°
///
- public XY Perpendicular()
- {
- return new XY(-y, x);
- }
+ public CellXY Perpendicular() => new(-y, x);
- public override bool Equals(object? obj) => obj is not null && obj is XY xy && this == xy;
+ public override bool Equals(object? obj) => (obj is not null) && (obj is CellXY xy) && (this == xy);
+ public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode();
- public override int GetHashCode()
+ ///
+ /// 解包
+ ///
+ public void Deconstruct(out int x, out int y)
{
- return this.x.GetHashCode() ^ this.y.GetHashCode();
+ x = this.x; y = this.y;
}
}
-public class GridXY : XY
-{
- public GridXY(int x, int y) : base(x, y) { }
- public GridXY(double angle, double length) : base(angle, length) { }
- public GridXY(XY Direction, double length) : base(Direction, length) { }
-}
-public class CellXY : XY
-{
- public CellXY(int x, int y) : base(x, y) { }
- public CellXY(double angle, double length) : base(angle, length) { }
- public CellXY(XY Direction, double length) : base(Direction, length) { }
-}
diff --git a/logic/Server/ArgumentOptions.cs b/logic/Server/ArgumentOptions.cs
index aa84a6e9..be712a7d 100755
--- a/logic/Server/ArgumentOptions.cs
+++ b/logic/Server/ArgumentOptions.cs
@@ -4,10 +4,10 @@ namespace Server
{
public class DefaultArgumentOptions
{
- public static string FileName = "xxxxxxxxxx";//
- public static string Token = "xxxxxxxxxx";//
- public static string Url = "xxxxxxxxxx";//
- public static string MapResource = "xxxxxxxxxx"; //
+ public const string FileName = "xxxxxxxxxx";//
+ public const string Token = "xxxxxxxxxx";//
+ public const string Url = "xxxxxxxxxx";//
+ public const string MapResource = "xxxxxxxxxx"; //
}
public class ArgumentOptions
{
@@ -64,7 +64,7 @@ public class ArgumentOptions
[Option('u', "url", Required = false, HelpText = "Web Url")]
public string Url { get; set; } = "114514";
[Option('m', "mapResource", Required = false, HelpText = "Map Resource Path")]
- public string mapResource { get; set; } = DefaultArgumentOptions.MapResource;
+ public string MapResource { get; set; } = DefaultArgumentOptions.MapResource;
[Option("requestOnly", Required = false, HelpText = "Only send web requests")]
public bool RequestOnly { get; set; } = false;
[Option("finalGame", Required = false, HelpText = "Whether it is the final game")]
diff --git a/logic/Server/CopyInfo.cs b/logic/Server/CopyInfo.cs
index 25c0dc0e..23068fe4 100755
--- a/logic/Server/CopyInfo.cs
+++ b/logic/Server/CopyInfo.cs
@@ -1,5 +1,7 @@
using GameClass.GameObj;
+using GameClass.GameObj.Areas;
using Preparation.Utility;
+using Utility = Preparation.Utility;
using Protobuf;
namespace Server
@@ -14,24 +16,24 @@ public static class CopyInfo
case GameObjType.Ship:
return Ship((Ship)gameObj, time);
case GameObjType.Home:
- return Home((GameClass.GameObj.Areas.Home)gameObj, time);
+ return Home((Home)gameObj, time);
case GameObjType.Bullet:
return Bullet((Bullet)gameObj);
case GameObjType.BombedBullet:
return BombedBullet((BombedBullet)gameObj);
case GameObjType.Resource:
- return Resource((GameClass.GameObj.Areas.Resource)gameObj);
+ return Resource((Resource)gameObj);
case GameObjType.Construction:
- GameClass.GameObj.Areas.Construction construction = (GameClass.GameObj.Areas.Construction)gameObj;
- if (construction.ConstructionType == Preparation.Utility.ConstructionType.Factory)
+ Construction construction = (Construction)gameObj;
+ if (construction.ConstructionType == Utility.ConstructionType.Factory)
return Factory(construction);
- else if (construction.ConstructionType == Preparation.Utility.ConstructionType.Community)
+ else if (construction.ConstructionType == Utility.ConstructionType.Community)
return Community(construction);
- else if (construction.ConstructionType == Preparation.Utility.ConstructionType.Fort)
+ else if (construction.ConstructionType == Utility.ConstructionType.Fort)
return Fort(construction);
return null;
case GameObjType.Wormhole:
- return Wormhole((GameClass.GameObj.Areas.Wormhole)gameObj);
+ return Wormhole((Wormhole)gameObj);
default: return null;
}
}
@@ -72,7 +74,7 @@ public static class CopyInfo
return msg;
}
- private static MessageOfObj? Home(GameClass.GameObj.Areas.Home player, long time)
+ private static MessageOfObj? Home(Home player, long time)
{
MessageOfObj msg = new()
{
@@ -125,7 +127,7 @@ private static MessageOfObj BombedBullet(BombedBullet bombedBullet)
return msg;
}
- private static MessageOfObj Resource(GameClass.GameObj.Areas.Resource resource)
+ private static MessageOfObj Resource(Resource resource)
{
MessageOfObj msg = new()
{
@@ -138,7 +140,7 @@ private static MessageOfObj Resource(GameClass.GameObj.Areas.Resource resource)
};
return msg;
}
- private static MessageOfObj Factory(GameClass.GameObj.Areas.Construction construction)
+ private static MessageOfObj Factory(Construction construction)
{
MessageOfObj msg = new()
{
@@ -153,7 +155,7 @@ private static MessageOfObj Factory(GameClass.GameObj.Areas.Construction constru
return msg;
}
- private static MessageOfObj Community(GameClass.GameObj.Areas.Construction construction)
+ private static MessageOfObj Community(Construction construction)
{
MessageOfObj msg = new()
{
@@ -168,7 +170,7 @@ private static MessageOfObj Community(GameClass.GameObj.Areas.Construction const
return msg;
}
- private static MessageOfObj Fort(GameClass.GameObj.Areas.Construction construction)
+ private static MessageOfObj Fort(Construction construction)
{
MessageOfObj msg = new()
{
@@ -182,7 +184,7 @@ private static MessageOfObj Fort(GameClass.GameObj.Areas.Construction constructi
};
return msg;
}
- private static MessageOfObj Wormhole(GameClass.GameObj.Areas.Wormhole wormhole)
+ private static MessageOfObj Wormhole(Wormhole wormhole)
{
MessageOfObj msg = new()
{
diff --git a/logic/Server/GameServer.cs b/logic/Server/GameServer.cs
index 9c41e555..a872c8f5 100755
--- a/logic/Server/GameServer.cs
+++ b/logic/Server/GameServer.cs
@@ -13,16 +13,16 @@ namespace Server
{
partial class GameServer : ServerBase
{
- private ConcurrentDictionary semaDict = new();
+ private readonly ConcurrentDictionary semaDict = new();
// private object semaDictLock = new();
protected readonly ArgumentOptions options;
- private HttpSender? httpSender;
+ private readonly HttpSender? httpSender;
private readonly object gameLock = new();
private MessageToClient currentGameInfo = new();
- private MessageOfObj currentMapMsg = new();
+ private readonly MessageOfObj currentMapMsg = new();
private readonly object newsLock = new();
- private List currentNews = [];
- private SemaphoreSlim endGameSem = new(0);
+ private readonly List currentNews = [];
+ private readonly SemaphoreSlim endGameSem = new(0);
protected readonly Game game;
private readonly uint spectatorMinPlayerID = 2023;
public int playerNum;
@@ -30,7 +30,7 @@ partial class GameServer : ServerBase
protected long[][] communicationToGameID; // 通信用的ID映射到游戏内的ID,0指向队伍1,1指向队伍2,通信中0为大本营,1-5为船
private readonly object messageToAllClientsLock = new();
public static readonly long SendMessageToClientIntervalInMilliseconds = 50;
- private MessageWriter? mwr = null;
+ private readonly MessageWriter? mwr = null;
private readonly object spectatorJoinLock = new();
public void StartGame()
@@ -96,13 +96,9 @@ private void SaveGameResult(string path)
result.Add("RedTeam", score[0]);
result.Add("BlueTeam", score[1]);
JsonSerializer serializer = new();
- using (StreamWriter sw = new(path))
- {
- using (JsonWriter writer = new JsonTextWriter(sw))
- {
- serializer.Serialize(writer, result);
- }
- }
+ using StreamWriter sw = new(path);
+ using JsonTextWriter writer = new(sw);
+ serializer.Serialize(writer, result);
}
protected void SendGameResult(int[] scores, int mode) // 天梯的 Server 给网站发消息记录比赛结果
@@ -115,7 +111,9 @@ private void OnGameEnd()
game.ClearAllLists();
mwr?.Flush();
if (options.ResultFileName != DefaultArgumentOptions.FileName)
- SaveGameResult(options.ResultFileName.EndsWith(".json") ? options.ResultFileName : options.ResultFileName + ".json");
+ SaveGameResult(options.ResultFileName.EndsWith(".json")
+ ? options.ResultFileName
+ : options.ResultFileName + ".json");
int[] scores = GetScore();
SendGameResult(scores, options.Mode);
endGameSem.Release();
@@ -210,7 +208,8 @@ private uint GetBirthPointIdx(long playerID) // 获取出生点位置
private bool ValidPlayerID(long playerID)
{
- if ((0 <= playerID && playerID < options.ShipCount) || (options.MaxShipCount <= playerID && playerID < options.MaxShipCount + options.HomeCount))
+ if ((0 <= playerID && playerID < options.ShipCount)
+ || (options.MaxShipCount <= playerID && playerID < options.MaxShipCount + options.HomeCount))
return true;
return false;
}
@@ -255,7 +254,7 @@ private MessageOfMap MapMsg()
public GameServer(ArgumentOptions options)
{
this.options = options;
- if (options.mapResource == DefaultArgumentOptions.MapResource)
+ if (options.MapResource == DefaultArgumentOptions.MapResource)
game = new(MapInfo.defaultMapStruct, options.TeamCount);
else
{
@@ -264,33 +263,31 @@ public GameServer(ArgumentOptions options)
{
string? line;
int i = 0, j = 0;
- using (StreamReader sr = new(options.mapResource))
+ using StreamReader sr = new(options.MapResource);
+ while (!sr.EndOfStream && i < GameData.MapRows)
{
- while (!sr.EndOfStream && i < GameData.MapRows)
+ if ((line = sr.ReadLine()) != null)
{
- if ((line = sr.ReadLine()) != null)
+ string[] nums = line.Split(' ');
+ foreach (string item in nums)
{
- string[] nums = line.Split(' ');
- foreach (string item in nums)
+ if (item.Length > 1)//以兼容原方案
+ {
+ map[i, j] = (uint)int.Parse(item);
+ }
+ else
+ {
+ //2022-04-22 by LHR 十六进制编码地图方案(防止地图编辑员瞎眼x
+ map[i, j] = (uint)MapEncoder.Hex2Dec(char.Parse(item));
+ }
+ j++;
+ if (j >= GameData.MapCols)
{
- if (item.Length > 1)//以兼容原方案
- {
- map[i, j] = (uint)int.Parse(item);
- }
- else
- {
- //2022-04-22 by LHR 十六进制编码地图方案(防止地图编辑员瞎眼x
- map[i, j] = (uint)MapEncoder.Hex2Dec(char.Parse(item));
- }
- j++;
- if (j >= GameData.MapCols)
- {
- j = 0;
- break;
- }
+ j = 0;
+ break;
}
- i++;
}
+ i++;
}
}
}
@@ -328,7 +325,7 @@ public GameServer(ArgumentOptions options)
{
try
{
- mwr = new MessageWriter(options.FileName, options.TeamCount, options.ShipCount);
+ mwr = new(options.FileName, options.TeamCount, options.ShipCount);
}
catch
{
@@ -338,7 +335,7 @@ public GameServer(ArgumentOptions options)
if (options.Url != DefaultArgumentOptions.Url && options.Token != DefaultArgumentOptions.Token)
{
- this.httpSender = new HttpSender(options.Url, options.Token);
+ httpSender = new(options.Url, options.Token);
}
}
}
diff --git a/logic/Server/HttpSender.cs b/logic/Server/HttpSender.cs
index fe8f349a..41a99aa7 100755
--- a/logic/Server/HttpSender.cs
+++ b/logic/Server/HttpSender.cs
@@ -4,8 +4,8 @@ namespace Server
{
class HttpSender(string url, string token)
{
- private string url = url;
- private string token = token;
+ private readonly string url = url;
+ private readonly string token = token;
// void Test()
// {
@@ -17,19 +17,17 @@ public async Task SendHttpRequest(int[] scores, int mode)
{
var request = new HttpClient();
request.DefaultRequestHeaders.Authorization = new("Bearer", token);
- using (var response = await request.PutAsync(url, JsonContent.Create(new
+ using var response = await request.PutAsync(url, JsonContent.Create(new
{
result = new TeamScore[]
{
- new() { team_id = 0, score = scores[0], },
- new() { team_id = 1, score = scores[1], },
+ new() { TeamID = 0, Score = scores[0], },
+ new() { TeamID = 1, Score = scores[1], },
},
- mode = mode
- })))
- {
- Console.WriteLine("Send to web successfully!");
- Console.WriteLine($"Web response: {await response.Content.ReadAsStringAsync()}");
- }
+ mode
+ }));
+ Console.WriteLine("Send to web successfully!");
+ Console.WriteLine($"Web response: {await response.Content.ReadAsStringAsync()}");
}
catch (Exception e)
{
@@ -41,7 +39,7 @@ public async Task SendHttpRequest(int[] scores, int mode)
internal class TeamScore
{
- public int team_id { get; set; } = 0;
- public int score { get; set; } = 0;
+ public int TeamID { get; set; } = 0;
+ public int Score { get; set; } = 0;
}
}
diff --git a/logic/Server/PlaybackServer.cs b/logic/Server/PlaybackServer.cs
index d00361d5..923b5827 100755
--- a/logic/Server/PlaybackServer.cs
+++ b/logic/Server/PlaybackServer.cs
@@ -9,15 +9,15 @@ namespace Server
class PlaybackServer(ArgumentOptions options) : ServerBase
{
protected readonly ArgumentOptions options = options;
- private int[] teamScore = new int[0];
- private ConcurrentDictionary semaDict = new();
+ private int[] teamScore = [];
+ private readonly ConcurrentDictionary semaDict = new();
// private object semaDictLock = new();
private MessageToClient? currentGameInfo = new();
private MessageOfObj currentMapMsg = new();
- private uint spectatorMinPlayerID = 2023;
+ private const uint spectatorMinPlayerID = 2023;
// private List spectatorList = new List();
public int TeamCount => options.TeamCount;
- private object spectatorJoinLock = new();
+ private readonly object spectatorJoinLock = new();
protected object spectatorLock = new();
protected bool isSpectatorJoin = false;
protected bool IsSpectatorJoin
@@ -35,7 +35,7 @@ protected bool IsSpectatorJoin
}
}
private bool IsGaming { get; set; } = true;
- private int[] finalScore = new int[0];
+ private int[] finalScore = [];
public int[] FinalScore
{
get
@@ -43,10 +43,12 @@ public int[] FinalScore
return finalScore;
}
}
- public override int[] GetMoney() => new int[0];
+ public override int[] GetMoney() => [];
public override int[] GetScore() => FinalScore;
- public override async Task AddPlayer(PlayerMsg request, IServerStreamWriter responseStream, ServerCallContext context)
+ public override async Task AddPlayer(PlayerMsg request,
+ IServerStreamWriter responseStream,
+ ServerCallContext context)
{
Console.WriteLine($"AddPlayer: {request.PlayerId}");
if (request.PlayerId >= spectatorMinPlayerID && options.NotAllowSpectator == false)
@@ -207,117 +209,115 @@ public override void WaitForEnd()
options.PlaybackSpeed = Math.Max(0.25, Math.Min(4.0, options.PlaybackSpeed));
timeInterval = (int)Math.Round(timeInterval / options.PlaybackSpeed);
}
- using (MessageReader mr = new(options.FileName))
- {
- teamScore = new int[mr.teamCount];
- finalScore = new int[mr.teamCount];
- int infoNo = 0;
- object cursorLock = new();
- var msgCurTop = Console.CursorTop;
- var msgCurLeft = Console.CursorLeft;
- var frt = new FrameRateTaskExecutor
- (
- loopCondition: () => true,
- loopToDo: () =>
- {
- MessageToClient? msg = null;
+ using MessageReader mr = new(options.FileName);
+ teamScore = new int[mr.teamCount];
+ finalScore = new int[mr.teamCount];
+ int infoNo = 0;
+ object cursorLock = new();
+ var msgCurTop = Console.CursorTop;
+ var msgCurLeft = Console.CursorLeft;
+ var frt = new FrameRateTaskExecutor
+ (
+ loopCondition: () => true,
+ loopToDo: () =>
+ {
+ MessageToClient? msg = null;
- msg = mr.ReadOne();
- if (msg == null)
- {
- Console.WriteLine("The game doesn't come to an end because of timing up!");
- IsGaming = false;
- ReportGame(msg);
- return false;
- }
+ msg = mr.ReadOne();
+ if (msg == null)
+ {
+ Console.WriteLine("The game doesn't come to an end because of timing up!");
+ IsGaming = false;
ReportGame(msg);
- lock (cursorLock)
- {
- var curTop = Console.CursorTop;
- var curLeft = Console.CursorLeft;
- Console.SetCursorPosition(msgCurLeft, msgCurTop);
- Console.WriteLine($"Sending messages... Current message number: {infoNo}.");
- Console.SetCursorPosition(curLeft, curTop);
- }
- if (msg != null)
+ return false;
+ }
+ ReportGame(msg);
+ lock (cursorLock)
+ {
+ var curTop = Console.CursorTop;
+ var curLeft = Console.CursorLeft;
+ Console.SetCursorPosition(msgCurLeft, msgCurTop);
+ Console.WriteLine($"Sending messages... Current message number: {infoNo}.");
+ Console.SetCursorPosition(curLeft, curTop);
+ }
+ if (msg != null)
+ {
+ foreach (var item in msg.ObjMessage)
{
- foreach (var item in msg.ObjMessage)
- {
- if (item.TeamMessage != null)
- teamScore[item.TeamMessage.TeamId] = item.TeamMessage.Score;
+ if (item.TeamMessage != null)
+ teamScore[item.TeamMessage.TeamId] = item.TeamMessage.Score;
- }
}
+ }
- ++infoNo;
- if (msg == null)
- {
- Console.WriteLine("No game information in this file!");
- IsGaming = false;
- ReportGame(msg);
- return false;
- }
- if (msg.GameState == GameState.GameEnd)
- {
- Console.WriteLine("Game over normally!");
- IsGaming = false;
- finalScore[0] = msg.AllMessage.BlueTeamScore;
- finalScore[1] = msg.AllMessage.RedTeamScore;
- ReportGame(msg);
- return false;
- }
- return true;
- },
- timeInterval: timeInterval,
- finallyReturn: () => 0
- )
- { AllowTimeExceed = true, MaxTolerantTimeExceedCount = 5 };
+ ++infoNo;
+ if (msg == null)
+ {
+ Console.WriteLine("No game information in this file!");
+ IsGaming = false;
+ ReportGame(msg);
+ return false;
+ }
+ if (msg.GameState == GameState.GameEnd)
+ {
+ Console.WriteLine("Game over normally!");
+ IsGaming = false;
+ finalScore[0] = msg.AllMessage.BlueTeamScore;
+ finalScore[1] = msg.AllMessage.RedTeamScore;
+ ReportGame(msg);
+ return false;
+ }
+ return true;
+ },
+ timeInterval: timeInterval,
+ finallyReturn: () => 0
+ )
+ { AllowTimeExceed = true, MaxTolerantTimeExceedCount = 5 };
- Console.WriteLine("The server is well prepared! Please MAKE SURE that you have opened all the clients to watch the game!");
- Console.WriteLine("If ALL clients have opened, press any key to start.");
- Console.ReadKey();
+ Console.WriteLine("The server is well prepared! Please MAKE SURE that you have opened all the clients to watch the game!");
+ Console.WriteLine("If ALL clients have opened, press any key to start.");
+ Console.ReadKey();
- new Thread
- (
- () =>
+ new Thread
+ (
+ () =>
+ {
+ var rateCurTop = Console.CursorTop;
+ var rateCurLeft = Console.CursorLeft;
+ lock (cursorLock)
+ {
+ rateCurTop = Console.CursorTop;
+ rateCurLeft = Console.CursorLeft;
+ Console.WriteLine($"Send message to clients frame rate: {frt.FrameRate}");
+ }
+ while (!frt.Finished)
{
- var rateCurTop = Console.CursorTop;
- var rateCurLeft = Console.CursorLeft;
lock (cursorLock)
{
- rateCurTop = Console.CursorTop;
- rateCurLeft = Console.CursorLeft;
+ var curTop = Console.CursorTop;
+ var curLeft = Console.CursorLeft;
+ Console.SetCursorPosition(rateCurLeft, rateCurTop);
Console.WriteLine($"Send message to clients frame rate: {frt.FrameRate}");
+ Console.SetCursorPosition(curLeft, curTop);
}
- while (!frt.Finished)
- {
- lock (cursorLock)
- {
- var curTop = Console.CursorTop;
- var curLeft = Console.CursorLeft;
- Console.SetCursorPosition(rateCurLeft, rateCurTop);
- Console.WriteLine($"Send message to clients frame rate: {frt.FrameRate}");
- Console.SetCursorPosition(curLeft, curTop);
- }
- Thread.Sleep(1000);
- }
+ Thread.Sleep(1000);
}
- )
- { IsBackground = true }.Start();
+ }
+ )
+ { IsBackground = true }.Start();
- lock (cursorLock)
- {
- msgCurLeft = Console.CursorLeft;
- msgCurTop = Console.CursorTop;
- Console.WriteLine("Sending messages...");
- }
- frt.Start();
+ lock (cursorLock)
+ {
+ msgCurLeft = Console.CursorLeft;
+ msgCurTop = Console.CursorTop;
+ Console.WriteLine("Sending messages...");
}
+ frt.Start();
}
}
finally
{
- teamScore ??= new int[0];
+ teamScore ??= [];
}
}
}
diff --git a/logic/Server/Program.cs b/logic/Server/Program.cs
index a85fe979..ad4cf179 100755
--- a/logic/Server/Program.cs
+++ b/logic/Server/Program.cs
@@ -50,12 +50,12 @@ static int Main(string[] args)
{
Console.WriteLine(welcome);
}
- Console.WriteLine("Server begins to run: " + options.ServerPort.ToString());
+ Console.WriteLine($"Server begins to run: {options.ServerPort}");
try
{
var server = CreateServer(options);
- Grpc.Core.Server rpcServer = new(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
+ Grpc.Core.Server rpcServer = new([new ChannelOption(ChannelOptions.SoReuseport, 0)])
{
Services = { AvailableService.BindService(server) },
Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) }