using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.Diagnostics; namespace BilaPani { public partial class MainForm : Form { private List> mapa = new List>(); private List FoundPath = new List(); private List Blacklist = new List(); private int MapWidth = 0; private int MapHeight = 0; private MapField TeleField = new MapField('s', 90, 90); private MapField CurField = new MapField('s', 90, 90); private List Zvedove = new List(); public MainForm() { InitializeComponent(); } private void inputFileDialogButton_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.FileName = inputFilePathBox.Text; ofd.CheckFileExists = true; ofd.CheckPathExists = true; if (ofd.ShowDialog() == DialogResult.OK) { inputFilePathBox.Text = ofd.FileName; } } private void loadInputFile_Click(object sender, EventArgs e) { if (!File.Exists(inputFilePathBox.Text)) { MessageBox.Show("Zadaná cesta k souboru je neplatná.", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } inputFilePathBox.Enabled = false; inputFileDialogButton.Enabled = false; loadInputFile.Enabled = false; krokovac.Enabled = false; mapa.Clear(); FoundPath.Clear(); Blacklist.Clear(); StreamReader reader = new StreamReader(inputFilePathBox.Text); bool isFirst = true; int lineNum = -1; while (!reader.EndOfStream) { lineNum++; string inputLine = reader.ReadLine(); if (isFirst) { isFirst = false; string buffer = ""; foreach (char c in inputLine) { if (Char.IsDigit(c)) { buffer += c; } else { MapWidth = Int32.Parse(buffer) - 1; buffer = ""; } } if (MapHeight == 0) { MapHeight = Int32.Parse(buffer) - 1; } } else { List buffer = new List(); List movementsBuffer = new List(); bool parsingMovements = false; int x = 1; foreach (char c in inputLine) { if (c == '&' || c == 'X' || c == '.' || c == '#') { buffer.Add(new MapField(c, x, lineNum)); if (c == '#') { TeleField = new MapField(c, x, lineNum); } else if (c == '&') { CurField = new MapField(c, x, lineNum); } x++; } else if (c == '@') { buffer.Add(new MapField(c, x, lineNum)); parsingMovements = true; } else if (parsingMovements) { if (c == '<' || c == '>' || c == '^' || c == 'v') { movementsBuffer.Add(c); } else { if (movementsBuffer.Count < 2) { throw new ApplicationException(); } Zved z = new Zved(x, lineNum, movementsBuffer); Zvedove.Add(z); x++; parsingMovements = false; } } else { throw new Exception("Unknown map character"); } } if (parsingMovements) { if (movementsBuffer.Count < 2) { throw new ApplicationException("Not enough movements in buffer"); } Zved z = new Zved(x, lineNum, movementsBuffer); Zvedove.Add(z); } mapa.Add(buffer); } } RenderMap(drawingCanvas.CreateGraphics()); } private void RenderMap(Graphics g) { int fieldHeight = 20; int fieldWidth = 20; int X = 0; int Y = 0; g.Clear(Color.White); foreach (List mapRow in mapa) { X = 0; for (int i = 0; i <= MapWidth; i++) { Bitmap b = new Bitmap(20, 20); switch (mapRow[i].Type) { case '&': b = BilaPani.Properties.Resources.pani; break; case '#': b = BilaPani.Properties.Resources.televize; break; case '.': b = BilaPani.Properties.Resources.dlazdice; break; case '@': b = BilaPani.Properties.Resources.zved; break; case 'X': b = BilaPani.Properties.Resources.zed; break; } g.DrawImage(b, X, Y, fieldWidth, fieldHeight); X += fieldWidth; } Y += fieldHeight; } SearchForWay(); if (FoundPath.Count == 0) { MessageBox.Show("Nebyla nalezena žádná cesta do 2500 kroků.", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { List newHistory = new List(); MapField last = new MapField('x', 10, 10); foreach (MapField m in FoundPath) { if (m != last) { newHistory.Add(m); last = m; } } MessageBox.Show("Byla nalezena cesta z původní lokace k televizi, o počtu kroků " + FoundPath.Count, "Informace", MessageBoxButtons.OK, MessageBoxIcon.Information); foreach (MapField m in FoundPath) { g.FillRectangle(Brushes.Green, ((m.X) * 20) + 5, ((m.Y) * 20) + 5, 10, 10); } /*inputFilePathBox.Enabled = true; inputFileDialogButton.Enabled = true; loadInputFile.Enabled = true;*/ krokovac.Maximum = FoundPath.Count; krokovac.Value = 1; krokovac.Enabled = true; } } public void SearchForWay() { List history = new List(); if (TeleField.X == 90) { throw new Exception("Television not set"); } foreach (List mapRow in mapa) { foreach (MapField mapItem in mapRow) { mapItem.CalcVal(TeleField); } } // Performance limit to not run forever but only for 1000 moves at max. for (int move = 0; move < 2500; move++) { List Neighbours = new List(4); if (move == 0 && CurField.Type != '&') { throw new ApplicationException("Chyba @279"); } if (CurField.Y > 0 && mapa[CurField.Y - 1][CurField.X].Type != 'X') // 2 { Neighbours.Add(mapa[CurField.Y - 1][CurField.X]); } if (CurField.Y < MapHeight && mapa[CurField.Y + 1][CurField.X].Type != 'X') // 1 { Neighbours.Add(mapa[CurField.Y + 1][CurField.X]); } if (CurField.X < MapWidth && mapa[CurField.Y][CurField.X + 1].Type != 'X') { Neighbours.Add(mapa[CurField.Y][CurField.X + 1]); } if (CurField.X > 0 && mapa[CurField.Y][CurField.X - 1].Type != 'X') { Neighbours.Add(mapa[CurField.Y][CurField.X - 1]); } MapField bestNeighbour = new MapField('X', 0, 0); int LowestVal = 999; foreach (MapField Neighbour in Neighbours) { if (Neighbour.Val < LowestVal) { if (Neighbour.Type == '#') { history.Add(Neighbour); FoundPath = history; return; } if (history.Count == 0 || history[history.Count - 1] != Neighbour) { if (history.Count > 1) { if (history[history.Count - 2] != Neighbour) { if (Blacklist.Contains(Neighbour) == false) { bestNeighbour = Neighbour; LowestVal = Neighbour.Val; } } } else { if (Blacklist.Contains(Neighbour) == false) { bestNeighbour = Neighbour; LowestVal = Neighbour.Val; } } } } } if (LowestVal == 999) { Blacklist.Add(CurField); // stay on current field which is now blacklisted! bestNeighbour = CurField; } history.Add(bestNeighbour); CurField = bestNeighbour; } } private void button1_Click(object sender, EventArgs e) { Bitmap b = new Bitmap(1600, 1600); drawingCanvas.DrawToBitmap(b, new Rectangle(0,0,1600,1600)); b.Save(@"D:\test.bmp"); } private void krokovac_ValueChanged(object sender, EventArgs e) { Graphics g = drawingCanvas.CreateGraphics(); int index = 1; int val = (int)krokovac.Value; foreach (MapField m in FoundPath) { if (index < val) { g.FillRectangle(Brushes.Orange, ((m.X) * 20) + 5, ((m.Y) * 20) + 5, 10, 10); } else { g.FillRectangle(Brushes.Green, ((m.X) * 20) + 5, ((m.Y) * 20) + 5, 10, 10); } index++; } } private void MainForm_Load(object sender, EventArgs e) { //MainForm.ActiveForm.Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); MainForm.ActiveForm.SetBounds(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); } } }