⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 destroyfinder.cs

📁 C#开发的运行于windows mobile PDA上的游戏
💻 CS
字号:
////////////////////////////////////////////////
// 
// Project: Lines.NET
// Version: 1.1
// Author:  Vladimir L.
// 
// homepage: http://www.boomsoft.org
// e-mail:   support@boomsoft.org
// 
// Copyright (c) 2003-2004, Boomsoft.org
// 

using System;
using System.Drawing;
using System.Collections;

namespace Lines.Core
{
	/// <summary>
	/// Encloses algorithm to find all balls that compose lines (vertical, horizontal 
	/// and diagonal) of <c>n</c> and more balls of the same color in a row.
	/// </summary>
	/// <remarks>
	/// <p>This class is used to determine balls that should be removed from a board
	/// at current step.</p>
	/// <p style="color:red"><i>The algorithms to find lines appearance are kind of clumsy by now, especially for
	/// diagonal lines, but they seem <b>to be working</b>. Probably I'll come back latter with 
	/// better implementation.</i></p>
	/// </remarks>
	public class DestroyFinder
	{
		/// <summary>
		/// Describes balls distributed over the board.
		/// </summary>
		private int[,] matrix;
		/// <summary>
		/// Defines the minimum amount of balls of the same color in a line which is enough
		/// to remove this line from a board.
		/// </summary>
		private int ballsInLine;

		/// <summary>
		/// Creates an instance of <c>DestroyFinder</c> class.
		/// </summary>
		/// <param name="matrix">describes balls distributed over the board. Each color is represented by 
		/// a number greater then <c>0</c>. <c>0</c> indicates an empty field of a board.</param>
		/// <param name="ballsInLine">defines the minimum amount of balls of the same color in a line,
		/// which is enough to remove this line from a board.</param>
		public DestroyFinder(int[,] matrix, int ballsInLine)
		{
			this.matrix = matrix;
			this.ballsInLine = ballsInLine;
		}
		
		/// <summary>
		/// Read-only property that returns the width of a board (matrix).
		/// </summary>
		public int Width
		{
			get {return matrix.GetLength(0);}
		}

		/// <summary>
		/// Read-only property that returns the height of a board (matrix).
		/// </summary>
		public int Height
		{
			get {return matrix.GetLength(1);}
		}

		/// <summary>
		/// Looks for the appearance of ball lines of the same color with length greater
		/// or equal to <see cref="ballsInLine"/> which is defined by the constructor of this 
		/// class.
		/// <seealso cref="DestroyFinder(int[,], int)"/>
		/// </summary>
		/// <returns>An array of locations on the board where the balls are placed that are 
		/// supposed to be removed.</returns>
		/// <remarks>
		/// This is the search for lines method itself. It consistently executes search over horizontal,
		/// vertical and both side diagonal lines to an appearance of balls of the same color with length
		/// greater or equal to defined one.
		/// </remarks>
		public Point[] FindLocations()
		{
			ArrayList locations = new ArrayList();
			
			// Horizontal lines
			AddUnique(locations, FindHorizontal());
			// Vertical lines
			AddUnique(locations, FindVertical());
			// NW-to-SE lines
			AddUnique(locations, FindDiagonal());
			// NE-to-SW lines
			AddUnique(locations, FindDiagonalBackward());
			
			Point[] result = new Point[locations.Count];
			for (int i = 0; i < locations.Count; i++)
			{
				result[i] = (Point)locations[i];
			}

			return result;
		}

		/// <summary>
		/// Helps to fill an array list with only positions (<see cref="System.Drawing.Point"/>) that
		/// are unique to this array.
		/// </summary>
		/// <param name="addTo">the array list where new positions supposed to be add to.</param>
		/// <param name="addFrom">the array list that encloses new positions.</param>
		/// <remarks>
		/// This method will add to array list <c>addTo</c> only those positions from array list
		/// <c>addFrom</c>, which are not yet enclosed by this array. This method is used to avoid
		/// duplicates in output.
		/// </remarks>
		private void AddUnique(ArrayList addTo, ArrayList addFrom)
		{
			for (int i = 0; i < addFrom.Count; i++)
			{
				Point pos = (Point)addFrom[i];
				bool unique = true;
				for (int j = 0; j < addTo.Count; j++)
				{
					if (((Point)addTo[j]) == pos)
					{
						unique = false;
						break;
					}
				}
				if (unique)
				{
					addTo.Add(pos);
				}
			}
		}

		/// <summary>
		/// Looks up for <b>horizontal</b> lines of balls of the same color.
		/// </summary>
		/// <returns>An array list of positions (<see cref="System.Drawing.Point"/>) of balls that supposed 
		/// to be removed from the board at current step.</returns>
		private ArrayList FindHorizontal()
		{
			ArrayList locations = new ArrayList();

			for (int y = 0; y < Height; y++)
			{
				// Each horizontal line
				int length = 0;
				int x = 0;
				int color = -1;
				while (x < Width)
				{
					int newColor = matrix[x, y];
					if ((newColor > 0) && (newColor == color))
					{
						length++;
					} 
					else 
					{
						if (length >= ballsInLine)
						{
							for (int i = 0; i < length; i++)
							{
								locations.Add(new Point(x - i - 1, y));
							}
						}

						if (newColor > 0)
						{
							length = 1;
							color = newColor;
						}
						else
						{
							length = 0;
							color = -1;
						}
					}
					x++;
				}
				if (length >= ballsInLine)
				{
					for (int i = 0; i < length; i++)
					{
						locations.Add(new Point(x - i - 1, y));
					}
				}
			}

			return locations;
		}

		/// <summary>
		/// Looks up for <b>vertical</b> lines of balls of the same color.
		/// </summary>
		/// <returns>An array list of positions (<see cref="System.Drawing.Point"/>) of balls that supposed 
		/// to be removed from the board at current step.</returns>
		private ArrayList FindVertical()
		{
			ArrayList locations = new ArrayList();

			for (int x = 0; x < Width; x++)
			{
				// Each vertical line
				int length = 0;
				int y = 0;
				int color = -1;
				while (y < Height)
				{
					int newColor = matrix[x, y];
					if ((newColor > 0) && (newColor == color))
					{
						length++;
					} 
					else 
					{
						if (length >= ballsInLine)
						{
							for (int i = 0; i < length; i++)
							{
								locations.Add(new Point(x, y - i - 1));
							}
						}

						if (newColor > 0)
						{
							length = 1;
							color = newColor;
						}
						else
						{
							length = 0;
							color = -1;
						}
					}
					y++;
				}
				if (length >= ballsInLine)
				{
					for (int i = 0; i < length; i++)
					{
						locations.Add(new Point(x, y - i - 1));
					}
				}
			}

			return locations;
		}
		
		/// <summary>
		/// Looks up for <b>diagonal</b> (NW-to-SE oriented) lines of balls of the same color.
		/// </summary>
		/// <returns>An array list of positions (<see cref="System.Drawing.Point"/>) of balls that supposed 
		/// to be removed from the board at current step.</returns>
		private ArrayList FindDiagonal()
		{
			ArrayList locations = new ArrayList();

			for (int line = ballsInLine - 1; line < (Width + Height - 2); line++)
			{
				// Each diagonal line
				int length = 0;
				int color = -1;
				int x = 0, y = line - x;
				for (; x <= line; x++, y = line - x)
				{
					if ((x < Width) && (y < Height))
					{
						int newColor = matrix[x, y];
						if ((newColor > 0) && (newColor == color))
						{
							length++;
						} 
						else 
						{
							if (length >= ballsInLine)
							{
								for (int i = 0; i < length; i++)
								{
									locations.Add(new Point(x - i - 1, y + i + 1));
								}
							}

							if (newColor > 0)
							{
								length = 1;
								color = newColor;
							}
							else
							{
								length = 0;
								color = -1;
							}
						}
					}
					else if (y < Height)
					{
						if (length >= ballsInLine)
						{
							for (int i = 0; i < length; i++)
							{
								locations.Add(new Point(x - i - 1, y + i + 1));
							}
							length = 0;
						}
					}
				}
				if (length >= ballsInLine)
				{
					for (int i = 0; i < length; i++)
					{
						locations.Add(new Point(x - i - 1, y + i + 1));
					}
				}
			}

			return locations;
		}
		
		/// <summary>
		/// Looks up for <b>diagonal</b> (NE-to-SW oriented) lines of balls of the same color.
		/// </summary>
		/// <returns>An array list of positions (<see cref="System.Drawing.Point"/>) of balls that supposed 
		/// to be removed from the board at current step.</returns>
		private ArrayList FindDiagonalBackward()
		{
			ArrayList locations = new ArrayList();

			for (int line = ballsInLine - 1; line < (Width + Height - 2); line++)
			{
				// Each backward diagonal line
				int length = 0;
				int color = -1;
				int x = 0, y = Height - 1 - line + x;
				for (; x <= line; x++, y = Height - 1 - line + x)
				{
					if ((x < Width) && (y >= 0) && (y < Height))
					{
						int newColor = matrix[x, y];
						if ((newColor > 0) && (newColor == color))
						{
							length++;
						} 
						else 
						{
							if (length >= ballsInLine)
							{
								for (int i = 0; i < length; i++)
								{
									locations.Add(new Point(x - i - 1, y - i - 1));
								}
							}

							if (newColor > 0)
							{
								length = 1;
								color = newColor;
							}
							else
							{
								length = 0;
								color = -1;
							}
						}
					}
					else if ((y >= 0) && (y < Height))
					{
						if (length >= ballsInLine)
						{
							for (int i = 0; i < length; i++)
							{
								locations.Add(new Point(x - i - 1, y - i - 1));
							}
							length = 0;
						}
					}
				}
				if (length >= ballsInLine)
				{
					for (int i = 0; i < length; i++)
					{
						locations.Add(new Point(x - i - 1, y - i - 1));
					}
				}
			}

			return locations;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -