智能提示:
///
/// 迷宫
///
internal class Maze : IDisposable
{
private MazeCell[,] cells;
private readonly Stack stack = new Stack();
private readonly Random rand = new Random();
private int _width, _height;
private Bitmap mazeBitmap; // 用于保存迷宫的位图
private float cellWidth;
private float cellHeight;
private Point playerPosition;
private float playerRadius;
private bool _isMove = true;
private int _canvasWidth;
private int _canvasHeight;
private MazeType _mazeType = MazeType.Default;
public Maze()
{
}
public Bitmap MazeBitmap => mazeBitmap;
public bool IsMove => _isMove;
public MazeType MazeType => _mazeType;
public int CanvasWidth
{
get => _canvasWidth;
set
{
_canvasWidth = value;
}
}
public int CanvasHeight
{
get => _canvasHeight;
set { _canvasHeight = value; }
}
private void GenerateMaze(MazeType mazeType)
{
switch(mazeType)
{
case MazeType.Default:
GenerateMaze_RecursiveBacktracking();
break;
case MazeType.DFS:
GenerateMaze_DFS();
break;
case MazeType.Prim:
GenerateMaze_Prim();
break;
case MazeType.RecursiveDivision:
GenerateMaze_RecursiveDivision();
break;
case MazeType.RecursiveBacktracking:
GenerateMaze_RecursiveBacktracking();
break;
}
}
///
/// 获取方向
///
///
private IEnumerable> GetDirections()
{
yield return Tuple.Create(-1, 0);
yield return Tuple.Create(1, 0);
yield return Tuple.Create(0, -1);
yield return Tuple.Create(0, 1);
}
#region 深度优先搜索算法
private void GenerateMaze_DFS()
{
// 选择迷宫的左上角的点作为起始点
int startX = 0;
int startY = 0;
// 使用DFS生成迷宫
GenerateMaze(startX, startY);
// 将起始点的左面的墙壁设为入口
cells[startX, startY].LeftWall = false;
// 找到迷宫的一个最远的边缘点,将它的边缘的墙壁设为出口
int maxDist = 0;
int endX = 0, endY = 0;
bool isBottomEdge = false;
for (int x = 0; x < _width; x++)
{
for (int y = 0; y < _height; y++)
{
int dist = Math.Abs(x - startX) + Math.Abs(y - startY);
if (dist > maxDist && (x == 0 || y == 0 || x == _width - 1 || y == _height - 1))
{
maxDist = dist;
endX = x;
endY = y;
isBottomEdge = (y == _height - 1);
}
}
}
if (isBottomEdge)
cells[endX, endY].BottomWall = false;
else
cells[endX, endY].RightWall = false;
}
private void GenerateMaze(int x, int y)
{
// 标记当前点已被访问
cells[x, y].Visited = true;
var tempData = GetDirections().OrderBy(_ => rand.Next());
// 随机访问四个方向
foreach (var dir in tempData)
{
int newX = x + dir.Item1, newY = y + dir.Item2;
if (newX >= 0 && newX < _width && newY >= 0 && newY < _height && !cells[newX, newY].Visited)
{
// 移除两个单元格之间的墙壁
if (dir.Item1 == -1)
{
cells[x, y].LeftWall = false;
cells[newX, newY].RightWall = false;
}
else if (dir.Item1 == 1)
{
cells[x, y].RightWall = false;
cells[newX, newY].LeftWall = false;
}
else if (dir.Item2 == -1)
{
cells[x, y].TopWall = false;
cells[newX, newY].BottomWall = false;
}
else if (dir.Item2 == 1)
{
cells[x, y].BottomWall = false;
cells[newX, newY].TopWall = false;
}
// 递归访问下一个点
GenerateMaze(newX, newY);
}
}
}
#endregion
#region 普里姆算法
private void GenerateMaze_Prim()
{
// 选择迷宫的一个随机点作为起始点
int startX = rand.Next(_width);
int startY = rand.Next(_height);
cells[startX, startY].Visited = true;
// 初始化边缘列表,包含起始点的所有邻居
Queue frontier = new Queue();
AddUnvisitedNeighborsToFrontier(cells[startX, startY], frontier);
// 使用Prim算法生成迷宫
while (frontier.Count > 0)
{
// 从边缘列表中选择一个单元格,更倾向于选择最早添加的单元格
var cell = frontier.Dequeue();
// 找到与这个单元格相邻的已访问的单元格
var neighbors = GetVisitedNeighbors(cell);
if (neighbors.Count > 0)
{
// 随机选择一个已访问的邻居
var neighbor = neighbors[rand.Next(neighbors.Count)];
// 移除两个单元格之间的墙壁
if (cell.X > neighbor.Item2.X) // 如果邻居在当前单元格的左侧
{
cell.LeftWall = false;
neighbor.Item2.RightWall = false;
}
else if (cell.X < neighbor.Item2.X) // 如果邻居在当前单元格的右侧
{
cell.RightWall = false;
neighbor.Item2.LeftWall = false;
}
else if (cell.Y > neighbor.Item2.Y) // 如果邻居在当前单元格的上方
{
cell.TopWall = false;
neighbor.Item2.BottomWall = false;
}
else if (cell.Y < neighbor.Item2.Y) // 如果邻居在当前单元格的下方
{
cell.BottomWall = false;
neighbor.Item2.TopWall = false;
}
// 将这个单元格标记为已访问,并将它的所有未访问的邻居添加到边缘列表中
cell.Visited = true;
AddUnvisitedNeighborsToFrontier(cell, frontier);
}
}
}
private void AddUnvisitedNeighborsToFrontier(MazeCell cell, Queue frontier)
{
foreach (var dir in GetDirections())
{
int newX = cell.X + dir.Item1, newY = cell.Y + dir.Item2;
if (newX >= 0 && newX < _width && newY >= 0 && newY < _height && !cells[newX, newY].Visited && !frontier.Contains(cells[newX, newY]))
frontier.Enqueue(cells[newX, newY]);
}
}
private List> GetVisitedNeighbors(MazeCell cell)
{
var visitedNeighbors = new List>();
foreach (var dir in GetDirections())
{
int newX = cell.X + dir.Item1, newY = cell.Y + dir.Item2;
if (newX >= 0 && newX < _width && newY >= 0 && newY < _height && cells[newX, newY].Visited)
visitedNeighbors.Add(Tuple.Create(dir.Item1, cells[newX, newY]));
}
return visitedNeighbors;
}
#endregion
#region 递归除法算法
private void GenerateMaze_RecursiveDivision()
{
// 初始化迷宫,所有的墙都被移除
for (int x = 0; x < _width; ++x)
{
for (int y = 0; y < _height; ++y)
{
cells[x, y].TopWall = y == 0;
cells[x, y].BottomWall = y == _height - 1;
cells[x, y].LeftWall = x == 0;
cells[x, y].RightWall = x == _width - 1;
}
}
// 递归分割迷宫
Divide(0, 0, _width - 1, _height - 1);
}
private void Divide(int x, int y, int width, int height)
{
if (width < 3 || height < 3)
return;
bool horizontal = rand.Next(2) == 0;
if (horizontal)
{
// 横向分割
int splitY = y + 2 + rand.Next(height - 3);
int holeX = x + rand.Next(width);
for (int i = x; i < x + width; ++i)
{
if (i != holeX)
{
cells[i, splitY].BottomWall = true;
if (splitY + 1 < _height)
{
cells[i, splitY + 1].TopWall = true;
}
}
}
Divide(x, y, width, splitY - y);
Divide(x, splitY + 1, width, y + height - splitY - 1);
}
else
{
// 纵向分割
int splitX = x + 2 + rand.Next(width - 3);
int holeY = y + rand.Next(height);
for (int i = y; i < y + height; ++i)
{
if (i != holeY)
{
cells[splitX, i].RightWall = true;
if (splitX + 1 < _width)
{
cells[splitX + 1, i].LeftWall = true;
}
}
}
Divide(x, y, splitX - x, height);
Divide(splitX + 1, y, x + width - splitX - 1, height);
}
}
#endregion
#region 时间回溯算法
private void GenerateMaze_RecursiveBacktracking()
{
// 初始化迷宫,所有的墙都存在
for (int x = 0; x < _width; ++x)
{
for (int y = 0; y < _height; ++y)
{
cells[x, y].TopWall = true;
cells[x, y].BottomWall = true;
cells[x, y].LeftWall = true;
cells[x, y].RightWall = true;
}
}
// 递归生成迷宫
VisitCell(rand.Next(_width), rand.Next(_height));
}
private void VisitCell(int x, int y)
{
// 标记当前单元格为已访问
cells[x, y].Visited = true;
// 对邻居单元格的顺序进行随机排序
foreach (var dir in GetDirections().OrderBy(d => rand.Next()))
{
int nx = x + dir.Item1;
int ny = y + dir.Item2;
// 如果邻居单元格在迷宫内并且未被访问过,则移除墙并递归访问邻居单元格
if (nx >= 0 && ny >= 0 && nx < _width && ny < _height && !cells[nx, ny].Visited)
{
RemoveWall(x, y, dir);
RemoveWall(nx, ny, Tuple.Create(-dir.Item1, -dir.Item2));
VisitCell(nx, ny);
}
}
}
private void RemoveWall(int x, int y, Tuple direction)
{
if (direction.Equals(Tuple.Create(-1, 0))) // Left
{
cells[x, y].LeftWall = false;
}
else if (direction.Equals(Tuple.Create(1, 0))) // Right
{
cells[x, y].RightWall = false;
}
else if (direction.Equals(Tuple.Create(0, -1))) // Up
{
cells[x, y].TopWall = false;
}
else if (direction.Equals(Tuple.Create(0, 1))) // Down
{
cells[x, y].BottomWall = false;
}
}
#endregion
public void CreateMaze(int width, int height, int canvasWidth, int canvasHeight, MazeType mazeType= MazeType.Default,bool createOrUpdate=true)
{
mazeBitmap?.Dispose();
_isMove = true;
if (createOrUpdate)
{
playerPosition = new Point(0, 0); // 初始位置在迷宫的左上角
stack.Clear();
_width = width;
_height = height;
cells = new MazeCell[width, height];
mazeBitmap = new Bitmap(width, height);
_mazeType = mazeType;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
cells[x, y] = new MazeCell(x, y);
}
}
}
GenerateMaze(mazeType);
// 生成迷宫后,将其绘制到位图上
mazeBitmap = new Bitmap(canvasWidth, canvasHeight);
using (var g = Graphics.FromImage(mazeBitmap))
{
DrawMaze(g, canvasWidth, canvasHeight);
}
}
private void DrawMaze(Graphics g, int canvasWidth, int canvasHeight)
{
int tempW = canvasWidth - 1;
_canvasWidth = tempW;
_canvasHeight = canvasHeight - 1;
cellWidth = (float)_canvasWidth / _width;
cellHeight = (float)_canvasHeight / _height;
playerRadius = Math.Min(cellWidth, cellHeight) / 4;
float lineWidth = 1f; // 线条的宽度
float halfLineWidth = lineWidth / 2f; // 线条宽度的一半
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
//g.SmoothingMode = SmoothingMode.AntiAlias;
// 先绘制所有的垂直线
for (int x = 0; x <= _width; x++)
{
float left = x * cellWidth;
for (int y = 0; y < _height; y++)
{
var cell = cells[Math.Min(x, _width - 1), y];
float top = y * cellHeight;
float bottom = (y + 1) * cellHeight;
if ((cell.LeftWall || x == _width) && !(x == _width && y == _height - 1))
g.DrawLine(Pens.Black, left, top - halfLineWidth, left, bottom + halfLineWidth);
}
}
// 再绘制所有的水平线
for (int y = 0; y <= _height; y++)
{
float top = y * cellHeight;
for (int x = 0; x < _width; x++)
{
var cell = cells[x, Math.Min(y, _height - 1)];
float left = x * cellWidth;
float right = (x + 1) * cellWidth;
if ((cell.TopWall || y == _height) && !(x == _width - 1 && y == _height))
g.DrawLine(Pens.Black, left - halfLineWidth, top, right + halfLineWidth, top);
}
}
}
public void Draw(Graphics g, int canvasWidth, int canvasHeight)
{
if (cells == null)
return;
int tempW = canvasWidth - 1;
if (tempW != _canvasWidth)
{
CreateMaze(_width, _height, canvasWidth, canvasHeight, MazeType,false);
}
// 首先,绘制保存的迷宫位图
g.DrawImage(mazeBitmap, 0, 0, canvasWidth, canvasHeight);
// 在玩家位置处绘制一个小黑圆
float playerX = (playerPosition.X + 0.5f) * cellWidth; // 玩家的X坐标
float playerY = (playerPosition.Y + 0.5f) * cellHeight; // 玩家的Y坐标
g.FillEllipse(Brushes.Black, playerX - playerRadius, playerY - playerRadius, 2 * playerRadius, 2 * playerRadius);
// 在出口处写上"出口"
//Font font = new Font("Arial", 16); // 设置字体和大小
//float exitX = (_width - 2f) * cellWidth; // 出口的X坐标
//float exitY = (_height - 1f) * cellHeight; // 出口的Y坐标
//g.DrawString("出口", font, Brushes.Black, exitX, exitY);
}
public MoveResult Move(KeyEventArgs e)
{
if (cells == null || !_isMove)
return new MoveResult();
Point newPosition = playerPosition;
switch (e.KeyCode)
{
case Keys.Up:
newPosition.Y--;
break;
case Keys.Down:
newPosition.Y++;
break;
case Keys.Left:
newPosition.X--;
break;
case Keys.Right:
newPosition.X++;
break;
}
return Move(newPosition);
}
public MoveResult Move(Point newPosition)
{
// 计算小黑点移动前后的矩形区域
Rectangle oldRect = GetPlayerRect(playerPosition);
bool status = false;
if (newPosition.X < 0 || newPosition.Y < 0)
{
goto Result;
}
int directionX = newPosition.X - playerPosition.X;
if (directionX != 0)
{
if (directionX > 0)
{
if (newPosition.X < _width && !cells[playerPosition.X, playerPosition.Y].RightWall && !cells[newPosition.X, newPosition.Y].LeftWall)
{
playerPosition = newPosition;
status = true;
goto Result;
}
}
else
{
if (newPosition.X >= 0 && !cells[playerPosition.X, playerPosition.Y].LeftWall && !cells[newPosition.X, newPosition.Y].RightWall)
{
playerPosition = newPosition;
status = true;
goto Result;
}
}
}
int directionY = newPosition.Y - playerPosition.Y;
if (directionY != 0)
{
if (directionY > 0)
{
if (newPosition.Y < _height && !cells[playerPosition.X, playerPosition.Y].BottomWall && !cells[newPosition.X, newPosition.Y].TopWall)
{
playerPosition = newPosition;
status = true;
goto Result;
}
}
else
{
if (newPosition.Y >= 0 && !cells[playerPosition.X, playerPosition.Y].TopWall && !cells[newPosition.X, newPosition.Y].BottomWall)
{
playerPosition = newPosition;
status = true;
goto Result;
}
}
}
// goto Result;
Result:
Rectangle newRect = GetPlayerRect(newPosition);
bool isWin = playerPosition.X == _width - 1 && playerPosition.Y == _height - 1;
_isMove = !isWin;
return new MoveResult
{
IsInvalidate = status,
IsWin = isWin,
OldRect = oldRect,
NewRect = newRect
};
}
private Rectangle GetPlayerRect(Point position)
{
int x = (int)Math.Round(position.X * cellWidth, 0);
int y = (int)Math.Round(position.Y * cellHeight, 0);
return new Rectangle(x, y, (int)Math.Round(cellWidth, 0), (int)Math.Round(cellHeight, 0));
}
public Bitmap DrawPath(Bitmap bitmap)
{
if (mazeBitmap == null)
return null;
var path = FindPath();
if (bitmap == null)
bitmap = new Bitmap(_canvasWidth, _canvasHeight);
// 创建一个Graphics对象
using (Graphics g = Graphics.FromImage(bitmap))
{
// 绘制路径
if (path != null)
{
var pathPen = new Pen(Color.Red, 2); // 使用红色画笔来绘制路径
for (int i = 0; i < path.Count - 1; i++)
{
float x1 = (path[i].X + 0.5f) * cellWidth;
float y1 = (path[i].Y + 0.5f) * cellHeight;
float x2 = (path[i + 1].X + 0.5f) * cellWidth;
float y2 = (path[i + 1].Y + 0.5f) * cellHeight;
g.DrawLine(pathPen, x1, y1, x2, y2);
}
}
}
return bitmap;
}
public List FindPath()
{
var start = cells[0, 0];
var end = cells[_width - 1, _height - 1];
var queue = new Queue();
var prev = new Dictionary();
queue.Enqueue(start);
while (queue.Count > 0)
{
var cell = queue.Dequeue();
if (cell == end)
{
var path = new List();
while (cell != start)
{
path.Add(cell);
cell = prev[cell];
}
path.Add(start);
path.Reverse();
return path;
}
foreach (var neighbor in GetNeighbors(cell))
{
if (prev.ContainsKey(neighbor))
continue;
prev[neighbor] = cell;
queue.Enqueue(neighbor);
}
}
return null; // 没有找到路径
}
private IEnumerable GetNeighbors(MazeCell cell)
{
var neighbors = new List();
if (cell.X > 0 && !cell.LeftWall)
neighbors.Add(cells[cell.X - 1, cell.Y]);
if (cell.X < _width - 1 && !cell.RightWall)
neighbors.Add(cells[cell.X + 1, cell.Y]);
if (cell.Y > 0 && !cell.TopWall)
neighbors.Add(cells[cell.X, cell.Y - 1]);
if (cell.Y < _height - 1 && !cell.BottomWall)
neighbors.Add(cells[cell.X, cell.Y + 1]);
return neighbors;
}
public void Dispose()
{
mazeBitmap?.Dispose();
}
~Maze()
{
Dispose();
}
}
public class MazeCell
{
public int X { get; set; }
public int Y { get; set; }
public bool Visited { get; set; }
public bool TopWall = true, BottomWall = true, LeftWall = true, RightWall = true;
public MazeCell(int x, int y)
{
X = x;
Y = y;
Visited = false;
TopWall = BottomWall = LeftWall = RightWall = true;
}
}
public class MoveResult
{
public bool IsInvalidate { get; set; }
public Rectangle OldRect { get; set; }
public Rectangle NewRect { get; set; }
public bool IsWin { get; set; }
}
public enum MazeType
{
///
/// 默认RecursiveBacktracking
///
Default,
///
/// 深度优先搜索算法
///
DFS,
///
/// 普里姆算法
///
Prim,
///
/// 递归除法算法
///
RecursiveDivision,
///
/// 递归回溯算法
///
RecursiveBacktracking
}
FrmMain主窗体:
public partial class FrmMain : Form
{
private readonly Maze _maze;
private System.Windows.Forms.Timer _timer;
public FrmMain()
{
InitializeComponent();
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
_maze = new Maze();
}
private void FrmGame_Load(object sender, EventArgs e)
{
this.KeyPreview = true;
BindType(typeof(MazeType), this.cbMazeType, "Default");
}
private void BindType(Type type, ComboBox comboBox, string defaultValue)
{
var enumValues = Enum.GetValues(type);
var list = new List();
int index = 0, curIndex = 0;
foreach (Enum value in enumValues)
{
int hc = value.GetHashCode();
list.Add(new IdValues
{
Id = hc.ToString(),
Value = value.ToString(),
Standby = hc
});
if (value.ToString() == defaultValue)
index = curIndex;
curIndex++;
}
comboBox.ValueMember = "Id";
comboBox.DisplayMember = "Value";
comboBox.DataSource = list;
comboBox.SelectedIndex = index;
}
private void FrmGame_FormClosing(object sender, FormClosingEventArgs e)
{
_maze.Dispose();
this.Dispose();
}
private bool _isPlayGame = false;
public bool IsPlayGame
{
get => _isPlayGame;
set
{
if (_isPlayGame == value)
return;
_isPlayGame = value;
if (value)
{
btnPlayGame.ExecBeginInvoke(() =>
{
btnPlayGame.Text = "重新开始";
});
}
else
{
btnPlayGame.ExecBeginInvoke(() =>
{
btnPlayGame.Text = "开启游戏";
});
}
}
}
private void btnPlayGame_Click(object sender, EventArgs e)
{
if (IsPlayGame)
{
if (MessageBox.Show("正在游戏中,确认重新开始吗?", "迷宫游戏提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
{
plGame.Focus();
return;
}
}
if (_timer != null)
{
_timer.Stop();
_timer.Dispose();
_timer = null;
}
_isAutoMove = false;
IsPlayGame = true;
int w = 10, h = 8;
if (rbEasy.Checked)
{
w = 30;
h = 21;
}
else if (rbMedium.Checked)
{
w = 66;
h = 45;
}
else
{
w = 100;
h = 67;
}
using var g = plGame.CreateGraphics();
MazeType mazeType = (MazeType)(this.cbMazeType.Items[cbMazeType.SelectedIndex] as IdValues).Standby;
_maze.CreateMaze(w, h, plGame.Width, plGame.Height, mazeType);
plGame.Controls.Clear();
g.Clear(plGame.BackColor);
_maze.Draw(g, plGame.Width, plGame.Height);
_timer = new System.Windows.Forms.Timer();
_timer.Interval = 1000;
time = 0;
_timer.Tick += timer_Tick;
_timer.Start();
plGame.Focus();
}
long time = 0;
private void timer_Tick(object? sender, EventArgs e)
{
lblTime.ExecBeginInvoke(() =>
{
lblTime.Text = Compute(++time);
});
}
public string Compute(long time)
{
if (time < 60)
return $"00:{ChangeString(time)}";
long minute = time / 60;
if (minute < 60)
return $"{ChangeString(minute)}:{ChangeString(time % 60)}";
long hour = minute / 60;
return $"{ChangeString(hour)}:{Compute(time - hour * 3600)}";
}
private string ChangeString(long val)
{
return val.ToString("D2");
}
private void plGame_Paint(object sender, PaintEventArgs e)
{
plGame.Controls.Clear();
e.Graphics.Clear(plGame.BackColor);
_maze.Draw(e.Graphics, plGame.Width, plGame.Height);
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (_isAutoMove)
return;
base.OnKeyDown(e);
var result = _maze.Move(e);
RefreshResult(result);
}
private void RefreshResult(MoveResult result)
{
if (result.IsInvalidate)
{
plGame.ExecInvoke(() =>
{
// 重绘迷宫
plGame.Invalidate(result.OldRect);
plGame.Invalidate(result.NewRect);
});
if (result.IsWin)
{
IsPlayGame = false;
if (_timer != null)
{
_timer.Stop();
_timer.Dispose();
_timer = null;
}
MessageBox.Show("通过", "迷宫通过提示");
}
}
}
private void FrmMain_Activated(object sender, EventArgs e)
{
plGame.Focus();
}
///
/// 提示
///
///
///
private void btnPrompt_Click(object sender, EventArgs e)
{
if (_maze.MazeBitmap == null)
{
return;
}
Bitmap bmp = new Bitmap(plGame.Width, plGame.Height);
plGame.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
int size = 0;
if (rbEasy.Checked)
size = 0;
else if (rbMedium.Checked)
size = 1;
else
size = 2;
FrmPrompt frmPrompt = new FrmPrompt(_maze.DrawPath(bmp), size);
frmPrompt.Show();
plGame.Focus();
}
private bool _isAutoMove = false;
///
/// 一键通过
///
///
///
private void btnPass_Click(object sender, EventArgs e)
{
if (!_maze.IsMove)
return;
_isAutoMove = true;
Task.Run(() =>
{
var path = _maze.FindPath();
if (path != null)
{
Point point = new Point(0, 0);
foreach (var item in path)
{
if (!_isAutoMove)
break;
point.X = item.X;
point.Y = item.Y;
var result = _maze.Move(point);
RefreshResult(result);
plGame.ExecInvoke(() =>
{
plGame.Update();
});
Thread.Sleep(50);
}
}
_isAutoMove = false;
});
}
private void plGame_Resize(object sender, EventArgs e)
{
}
}
public class IdValues
{
public string Id { get; set; }
public string Value { get; set; }
public string Value2 { get; set; }
public string Value3 { get; set; }
public string Value4 { get; set; }
public string Value5 { get; set; }
public int Standby { get; set; }
public static bool operator ==(IdValues idValues, IdValues idValues2)
{
return idValues.Equals(idValues2);
}
public static bool operator !=(IdValues idValues, IdValues idValues2)
{
return !idValues.Equals(idValues2);
}
public override int GetHashCode()
{
var code = (Id, Value, Value2, Value3, Value4, Value5, Standby).GetHashCode();
return code;
}
public override bool Equals(object? obj)
{
return obj?.GetHashCode() == GetHashCode();
}
const int TARGET = 0x1F;
///
/// 将连续字段的哈希代码左移两位或更多位来加权各个哈希代码(最佳情况下,超出位 31 的位应环绕,而不是被丢弃)
///
///
///
///
public int ShiftAndWrap(int value, int positions = 3)
{
positions &= TARGET;
uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
uint wrapped = number >> (32 - positions);
return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0);
}
}