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

📄 citymap.cs

📁 game implemented java
💻 CS
字号:
using System;
using System.IO;
using System.Collections;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization.Formatters.Binary;


namespace WindowsApplication2
{
	/// <summary>
	/// The object that stores, loads, and saves map data.
	/// </summary>
	public class CityMap
	{
		private Scaler Map_Scale = new Scaler();
		private ArrayList streetSegs = new ArrayList();
		private IntersectionList intersections;
		private Random r;
		private int segCount, min_X, min_Y, max_X, max_Y;

		public CityMap()
		{
			//Initialize here to take advantage of good pseudo-random series
			//Seed is different for each map
			r = new Random();
			segCount = 0;
			min_X = Int32.MaxValue;
			min_Y = Int32.MaxValue;
			max_X = Int32.MinValue;
			max_Y = Int32.MinValue;
		}

		#region FHB file manipulation
		public void SaveMap(string fileName)
		{//Saves the Map and all associated data in a binary format that can be easily loaded
			ArrayList array = new ArrayList();
			array.Add(streetSegs);
			array.Add(intersections);
			array.Add(r);
			array.Add(segCount);
			array.Add(new Point(min_X,min_Y));
			array.Add(new Point(max_X,max_Y));
			array.Add(Map_Scale);

			Stream stream = File.Open(fileName, FileMode.OpenOrCreate);
			BinaryFormatter bf = new BinaryFormatter();
			bf.Serialize(stream, array);  // serialize the arraylist to the output stream here
			stream.Close();
		}
		public void LoadMap(string fileName)
		{//Load from a file created as above
			Stream stream = File.Open(fileName, FileMode.Open);
			BinaryFormatter bf = new BinaryFormatter();
     
			ArrayList array = (ArrayList) bf.Deserialize(stream); // deserialize the file to the object (must cast)
			stream.Close();
			streetSegs = (ArrayList)array[0];
			intersections = (IntersectionList)array[1];
			r = (Random)array[2];
			segCount = (int)array[3];
			min_X = ((Point)array[4]).X;
			min_Y = ((Point)array[4]).Y;
			max_X = ((Point)array[5]).X;
			max_Y = ((Point)array[5]).Y;
			Map_Scale = (Scaler)array[6];
		}
		#endregion

		#region CSV file manipulation
		public void ImportMap(StreamReader data)
		{//Needs expansion (and a helper form) to allow flexibility
			string myInputstring;

			try 
			{
				myInputstring = data.ReadLine();
				//Help align if file is a CSV
				//First line is ignored because it contains headers in my CSV file
				myInputstring = data.ReadLine();
				while (myInputstring != null)
				{
					string[] dataCells = myInputstring.Split(",".ToCharArray());
					MapSeg toAdd = new MapSeg(ParseInt(dataCells[1]),
						ParseInt(dataCells[2]), ParseInt(dataCells[3]),ParseInt(dataCells[4]));
					toAdd.StreetName = dataCells[5];
					if (Math.Max(toAdd.from.X,toAdd.to.X)>max_X) 
						max_X = Math.Max(toAdd.from.X,toAdd.to.X);
					if (Math.Min(toAdd.from.X,toAdd.to.X)<min_X) 
						min_X = Math.Min(toAdd.from.X,toAdd.to.X);
					if (Math.Max(toAdd.from.Y,toAdd.to.Y)>max_Y) 
						max_Y = Math.Max(toAdd.from.Y,toAdd.to.Y);
					if (Math.Min(toAdd.from.Y,toAdd.to.Y)<min_Y) 
						min_Y = Math.Min(toAdd.from.Y,toAdd.to.Y);
					streetSegs.Add(toAdd);
					segCount++;
					myInputstring = data.ReadLine();
				}
				MessageBox.Show("CitySim has successfully loaded "+segCount+" Street Segments."+Environment.NewLine
					+"Data Range: ("+min_X+","+min_Y+") to ("+max_X+","+max_Y+")","Load Successful");
			} 
			catch(Exception exc)
			{
				// Show the error to the user.
				MessageBox.Show("File could not be opened or read." + Environment.NewLine + 
					"Please verify that the filename is correct, and that it is properly formatted." + Environment.NewLine + 
					"Exception: " + exc.Message);
			}
			finally
			{
				// Close the object if it has been created.
				if (data != null)
				{
					data.Close();
				}
			}
			//All segments have been added, and Intersections must be discovered
			intersections = new IntersectionList(max_X,min_X);
			for (int i=0;i<segCount;i++)
			{
				MapSeg toLoad = (MapSeg)streetSegs[i];
				int index = intersections.pointSearch(toLoad.from);
				if (index < 0)
				{
					intersections.Add(new Intersection(toLoad.from,i));
					toLoad.From_Intersection = intersections.Count-1;
				}
				else
				{
					Intersection found = (Intersection)intersections[index];
					found.addConnection(i);
					toLoad.From_Intersection = index;
				}
				index = intersections.pointSearch(toLoad.to);
				if (index < 0)
				{
					intersections.Add(new Intersection(toLoad.to,i));
					toLoad.To_Intersection = intersections.Count-1;
				}
				else
				{
					Intersection found = (Intersection)intersections[index];
					found.addConnection(i);
					toLoad.To_Intersection = index;
				}
			}
			MessageBox.Show("Intersections successfully discovered."+Environment.NewLine+
				"City Sim has discovered and logged "+intersections.Count+" intersections."+Environment.NewLine+
				"");//"The shortest distance between two intersections is: "+intersections.shortestDist());
			Map_Scale.setRange(max_X,max_Y,min_X,min_Y);
			
			//Finally, intersections must be analyzed for thruStreets. Reporting is currently commented out.
			int [] totals = new int [30];
			int [] results = new int [30];
			for (int i=0;i<intersections.Count;i++)
			{
				Intersection toComplete = (Intersection)intersections[i];
				totals[toComplete.getConnections.Count]++;
				results[toComplete.analyze(this)]++;
			}
			/*string toDisplay = "Intersections Analyzed"+Environment.NewLine+"Successes: "+results[0]+Environment.NewLine;
			toDisplay += "Failures:"+Environment.NewLine;
			for (int i=1; i<totals.Length;i++)
			{
				toDisplay += i+": "+results[i]+" of "+totals[i]+Environment.NewLine;
			}
			MessageBox.Show (toDisplay);*/
		}
		#endregion

		#region Simple Properties
		public int getRandomMapSeg()
		{
			return r.Next(segCount);
		}
		public IntersectionList getIntersectionList
		{
			get {return intersections;}
		}
		public Scaler scale
		{
			get{return Map_Scale;}
			set{Map_Scale = value;}
		}
		public MapSeg getSegment (int id)
		{
			return (MapSeg)streetSegs[id];
		}
		#endregion

		public void PrepareSim()
		{//Initalize values, so multiple simulations can be run each session
			for (int i=0;i<streetSegs.Count;i++)
			{
				((MapSeg)streetSegs[i]).visits = 0;
				((MapSeg)streetSegs[i]).clearCars();
			}
		}
		public void SortCars()
		{//Allows the Drive function to assume that cars in MapSegs are sorted
			for (int i=0;i<streetSegs.Count;i++)
				this.getSegment(i).SortCars();
		}
		public void TestConnections()
		{//Debug only: Proves that maps are imported correctly
			int from = 0;
			int to = 0;
			for (int i=0; i<streetSegs.Count;i++)
			{
				MapSeg cur = (MapSeg)streetSegs[i];
				Intersection f_int = (Intersection)intersections[(int)cur.From_Intersection];
				Intersection t_int = (Intersection)intersections[(int)cur.To_Intersection];
				if(!f_int.checkConnection(i)){from++;}
				if(!t_int.checkConnection(i)){to++;}
			}
			MessageBox.Show("Errors: From = "+from+" and To = "+to);
		}
		public void drawMap (Graphics g, bool colorLines)
		{//Draws the map, Colors post-simulation report appropriately
			int MaxVisits = 0;
			Pen myPen = new Pen (Color.White,2);
			if (colorLines)
			{
				for (int i=0;i<streetSegs.Count;i++)
				{
					MapSeg toCheck = getSegment(i);
					if (toCheck.visits > MaxVisits)
						MaxVisits = toCheck.visits;
				}
				myPen.Width = 4;
			}
			g.SmoothingMode = SmoothingMode.HighQuality;
			for(int i=0;i<segCount;i++)
			{
				MapSeg needToDraw = (MapSeg)streetSegs[i];
				if (colorLines)
				{
					double percentage = needToDraw.visits/(double)MaxVisits;
					if (percentage == 0)
						continue;
					else if (percentage <=0.1)
						myPen.Color = Color.LightGray;
					else if (percentage <= 0.25)
						myPen.Color = Color.Orange;
					else if (percentage <= 0.5)
						myPen.Color = Color.Green;
					else
						myPen.Color = Color.Red;
				}
				g.DrawLine(myPen,Map_Scale.translate(needToDraw.from),Map_Scale.translate(needToDraw.to));
			}
		}
		public ArrayList getBlocks (PointF Oldp1, PointF Oldp2, int mode)
		{//Generates the list of blocks analyzed by the City_Blocks Form
			ArrayList toReturn = new ArrayList();
			Point p1 = scale.revert(Oldp1);
			Point p2 = scale.revert(Oldp2);
			int MXX = Math.Max(p1.X,p2.X);
			int MXY = Math.Max(p1.Y,p2.Y);
			int MNX = Math.Min(p1.X,p2.X);
			int MNY = Math.Min(p1.Y,p2.Y);
			double slope = (p1.Y - p2.Y)/(double)(p1.X - p2.X);
			int fudge = 1000;

			for (int i=0; i<streetSegs.Count;i++)
			{
				MapSeg cur = (MapSeg)streetSegs[i];
				switch(mode)
				{
					case Form1.SELECT_BOX: 
						if (cur.max_X() <= MXX && cur.max_Y() <= MXY && cur.min_X() >= MNX
							&& cur.min_Y() >= MNY)
						{
							toReturn.Add (i);
						}
						break;
					case Form1.SELECT_LINE:
						double yVal = slope * (cur.from.X - p1.X) + p1.Y;
						if (cur.max_X() <= MXX && cur.max_Y() <= MXY && cur.min_X() >= MNX
							&& cur.min_Y() >= MNY)
						{
							/*MessageBox.Show("From: ("+p1.X+","+p1.Y+")"+Environment.NewLine+
								"To: ("+p2.X+","+p2.Y+")"+Environment.NewLine+
								"Slope: "+slope+Environment.NewLine+
								"yVal 1: "+yVal+Environment.NewLine+
								"Real Y: "+cur.from.Y+Environment.NewLine+
								"Real X: "+cur.from.X+Environment.NewLine);*/
							if (cur.from.Y <= yVal + fudge && cur.from.Y >= yVal - fudge)
							{
								toReturn.Add (i);
								break;
							}
							yVal = slope * (cur.to.X - p1.X) + p1.Y;
							if (cur.to.Y <= yVal + fudge && cur.to.Y >= yVal - fudge)
							{toReturn.Add (i);}
						}
						break;
				}
			}
			MessageBox.Show ("Found "+toReturn.Count+" City Blocks");
			return toReturn;
		}
		public ArrayList getIntersections (PointF Oldp1, PointF Oldp2, int mode)
		{//Generates the list of intersections to be analyzed by one of the other two forms
			ArrayList toReturn = new ArrayList();
			Point p1 = scale.revert(Oldp1);
			Point p2 = scale.revert(Oldp2);
			int MXX = Math.Max(p1.X,p2.X);
			int MXY = Math.Max(p1.Y,p2.Y);
			int MNX = Math.Min(p1.X,p2.X);
			int MNY = Math.Min(p1.Y,p2.Y);
			double slope = (p1.Y - p2.Y)/(double)(p1.X - p2.X);
			int fudge = 1000;
			double min_dist = Double.MaxValue;

			for (int i=0; i<intersections.Count;i++)
			{
				Intersection cur = (Intersection)intersections[i];
				switch(mode)
				{
					case Form1.SELECT_BOX: 
						if (cur.getPoint.X <= MXX && cur.getPoint.Y <= MXY && cur.getPoint.X >= MNX
							&& cur.getPoint.Y >= MNY)
						{
							toReturn.Add (i);
						}
						break;
					case Form1.SELECT_LINE:
						double yVal = slope * (cur.getPoint.X - p1.X) + p1.Y;
						if (cur.getPoint.X <= MXX && cur.getPoint.Y <= MXY && cur.getPoint.X >= MNX
							&& cur.getPoint.Y >= MNY)
						{
							/*MessageBox.Show("From: ("+p1.X+","+p1.Y+")"+Environment.NewLine+
								"To: ("+p2.X+","+p2.Y+")"+Environment.NewLine+
								"Slope: "+slope+Environment.NewLine+
								"yVal 1: "+yVal+Environment.NewLine+
								"Real Y: "+cur.from.Y+Environment.NewLine+
								"Real X: "+cur.from.X+Environment.NewLine);*/
							if (cur.getPoint.Y <= yVal + fudge && cur.getPoint.Y >= yVal - fudge)
							{toReturn.Add (i);}
						}
						break;
					case Form1.SELECT_POINT:
						double xdiff = cur.getPoint.X - p2.X;  
						double ydiff = cur.getPoint.Y - p2.Y;  
						double dist = Math.Sqrt(xdiff * xdiff + ydiff * ydiff);  
						if (dist < min_dist)
						{
							//MessageBox.Show("Dist: "+dist+" Min: "+min_dist);
							min_dist = dist;
							toReturn.Clear();
							toReturn.Add(i);
						}
						break;
				}
			}
			MessageBox.Show ("Found "+toReturn.Count+" Intersections");
			return toReturn;
		}
		public void reRandomize()
		{//Because the randomization object is saved in .FHB files, this is the way to
		//run new random simulations on a previously saved map.  
			r = new Random();
		}

		#region Integer Parsing
		private int ParseInt(string str)
		{
			char[] chars = str.ToCharArray();
			string numeric = "";
			int round = 0;

			for(int i=0; i<chars.Length; i++)
			{
				if (chars[i] == '.')
				{
					try 
					{
						if (CharIsNumeric(chars[i+1])&& Convert.ToInt32(chars[i+1]) >= 53)
							round = 1;
					}
					catch {;}//if there is no following character, round down
					break;
				}
				else if(CharIsNumeric(chars[i]))
				{
					numeric += Convert.ToString(chars[i]);
				}
			}

			if(numeric != "")
				return Convert.ToInt32(numeric)+round;
			else
				return 0;
		}

		private bool CharIsNumeric(char c)
		{
			int charCode = Convert.ToInt32(c);
			if(charCode > 47 && charCode < 58)
				return true;
			else
				return false;
		}
		#endregion
	}
}

⌨️ 快捷键说明

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