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.Text.RegularExpressions; namespace zelva { public partial class Form1 : Form { /* const string com_left = "^left\\(([0-9]+)\\)"; const string com_right = "^right\\([0-9]+\\)"; const string com_pen = "^pen\\([0-9]+\\)"; const string com_forward = "^forward\\([0-9]+\\)"; */ const string com_univ = "^([a-zA-Z]+)\\((-?[0-9]+)\\)"; //pro obyčejné fce s jedním parametrem const string com_color = "^color\\(([0-9]+),([0-9]+),([0-9]+)\\)"; //pro barvu const string com_repeat = "^repeat\\((-?[0-9]+)\\)"; //pro příkaz repeat const string com_if = "^if\\((-?[0-9]+)\\)"; //pro podmínku const string com_define = "^define([a-z]+)\\(\\)"; //pro definici procedury const string com_func = "^([a-z]+)\\(\\)"; //nová definovaná procedura public struct Command { public string com; //typ příkazu public int par; //parametry public int par2,par3; public bool defined; //zda je standartní (false) nebo definovaná uživatelem (true) } public struct ZelvaPos { //zaznamenání údajů pro želvu public double x,y; public int angle; public int r,g,b; public int pen; } public struct ComList { //seznam příkazů (každý if, repeat a define má svůj seznam) public List commands; public int rep; //v případě repeat je zde uvedeno počet opakování (není pevně dané, během průběhu aplikace se mění) public string name; //v případě define je zde jméno procedury public int returnList; //kam se má program navrátit po skončení těchto příkazů public int returnStep; //(nastavuje se během průběhu) } public Bitmap bmp; public List commands; public List lists; public ZelvaPos zelva; public ZelvaPos lastZelva; public int actStep; public int actList; int totalfws; public Form1() { InitializeComponent(); bmp = new Bitmap(700,700); commands = new List(); lists = new List(); zelva.x = 0; zelva.y = 0; zelva.angle = 0; zelva.r = 0; zelva.g = 0; zelva.b = 0; lastZelva = zelva; } public void LoadCommands(string filename) { lists = new List(); zelva.x = 0; zelva.y = 0; zelva.angle = 90; zelva.r = 0; zelva.g = 0; zelva.b = 0; zelva.pen = 0; lastZelva = zelva; totalfws = 0; actStep = 0; actList = 0; Graphics g = Graphics.FromImage(bmp); g.FillRectangle(Brushes.White,new Rectangle(0,0,700,700)); g.Dispose(); commands = new List(); StreamReader sr = new StreamReader(filename); string coms = sr.ReadToEnd(); coms = coms.Replace("\n", ""); //všechny bílé znaky se odstraní coms = coms.Replace("\r", ""); coms = coms.Replace(" ", ""); coms = coms.Replace("\t", ""); coms = ComsFromString(coms, 0, -1, 0); Dictionary functions = new Dictionary(); for (int i = 0; i < lists.Count; i += 1) { if (lists[i].name != "") { functions.Add(lists[i].name, i); //zaznamenají se všechny funkce (jména) } } for (int i = 0; i < lists.Count; i += 1) { //if (lists[i].name != "") continue; ComList cc = lists[i]; for (int j = 0; j < cc.commands.Count; j += 1) { if (cc.commands[j].defined == true) { Command cmd = cc.commands[j]; cmd.par = functions[cmd.com]; cc.commands[j] = cmd; } } lists[i] = cc; } sr.Close(); } public string ComsFromString(string text, int depth, int fromlist, int fromstep) { ComList cc; //čtení příkazů z textu cc.commands = new List(); cc.rep = 0; cc.returnList = -1; cc.returnStep = -1; cc.name = ""; int id = lists.Count; lists.Add(cc); Command c; while (text != "") { if (text.StartsWith("}") == true) { text = text.Substring(1); break; } c.com = ""; c.par = 0; c.par2 = 0; c.par3 = 0; c.defined = false; Regex r; Match m; //použití regulárních výrazů r = new Regex(com_univ); m = r.Match(text); if (m.Success && m.Groups[1].Value!="repeat" && m.Groups[1].Value!="if") { c.com = m.Groups[1].Value; c.par = Convert.ToInt32(m.Groups[2].Value); int len = m.Groups[0].Length; text = text.Substring(len); cc.commands.Add(c); continue; } else { r = new Regex(com_color); m = r.Match(text); if (m.Success) { c.com = "color"; c.par = Convert.ToInt32(m.Groups[1].Value); c.par2 = Convert.ToInt32(m.Groups[2].Value); c.par3 = Convert.ToInt32(m.Groups[3].Value); int len = m.Groups[0].Length; text = text.Substring(len); cc.commands.Add(c); continue; } else { r = new Regex(com_repeat); m = r.Match(text); if (m.Success) { c.com = "repeat"; c.par = Convert.ToInt32(m.Groups[1].Value); c.par2 = lists.Count; int len = m.Groups[0].Length; text = text.Substring(len + 1); cc.commands.Add(c); text = ComsFromString(text, depth + 1, id, cc.commands.Count - 1); continue; } else { r = new Regex(com_if); m = r.Match(text); if (m.Success) { c.com = "if"; c.par = Convert.ToInt32(m.Groups[1].Value); c.par2 = lists.Count; int len = m.Groups[0].Length; text = text.Substring(len + 1); cc.commands.Add(c); text = ComsFromString(text, depth + 1, id, cc.commands.Count - 1); continue; } else { r = new Regex(com_define); m = r.Match(text); if (m.Success) { int len = m.Groups[0].Length; text = text.Substring(len + 1); text = ComsFromString(text, depth + 1, id, cc.commands.Count - 1); ComList ccc = lists[lists.Count - 1]; ccc.name = m.Groups[1].Value; lists[lists.Count - 1] = ccc; } else { r = new Regex(com_func); m = r.Match(text); if (m.Success) { c.com = m.Groups[1].Value; c.defined = true; int len = m.Groups[0].Length; text = text.Substring(len); cc.commands.Add(c); continue; } } } } } } } /*c.com = "return"; c.par = fromlist; c.par2 = fromstep; c.par3 = 0; cc.commands.Add(c); */ lists[id] = cc; return text; } public bool DoCommand(Command com) { //vykonání příkazu lastZelva = zelva; if (com.com == "left") zelva.angle += com.par; if (com.com == "right") zelva.angle -= com.par; if (com.com == "forward") { zelva.x += com.par * Math.Cos(zelva.angle * Math.PI / 180); zelva.y += com.par * Math.Sin(zelva.angle * Math.PI / 180); if (zelva.pen > 0) { Graphics g = Graphics.FromImage(bmp); g.DrawLine(new Pen(Color.FromArgb(zelva.r,zelva.g,zelva.b),zelva.pen), new Point((int)(lastZelva.x)+350,350-(int)(lastZelva.y)), new Point((int)(zelva.x)+350,350-(int)(zelva.y))); g.Dispose(); Graphics gg = pictureBox1.CreateGraphics(); gg.DrawImage(bmp, new Point(0, 0)); gg.Dispose(); return true; } } if (com.com == "pen") zelva.pen = com.par; if (com.com == "color") { zelva.r = com.par; zelva.g = com.par2; zelva.b = com.par3; } if (com.com == "repeat") { if (com.par > 0) { ComList cc = lists[com.par2]; cc.rep = com.par; cc.returnList = actList; cc.returnStep = actStep; lists[com.par2] = cc; actList = com.par2; actStep = -1; } } if (com.com == "if") { if (com.par>0) { ComList cc = lists[com.par2]; cc.returnList = actList; cc.returnStep = actStep; lists[com.par2] = cc; actStep = -1; actList = com.par2; } } if (com.defined == true) { ComList cc = lists[com.par]; cc.returnList = actList; cc.returnStep = actStep; lists[com.par] = cc; actStep = -1; actList = com.par; } return false; /*if (com.com == "return") { if (lists[actList].rep < 1) { actList = com.par; actStep = com.par2; } else { ComList cc = lists[actList]; cc.rep -= 1; lists[actList] = cc; actStep = -1; } }*/ } public void DrawKrun() { //nakreslení želvy Graphics g = pictureBox1.CreateGraphics(); Point pos = new Point((int)(zelva.x+350 -10),(int)(350-zelva.y -10)); Point phead = new Point((int)(zelva.x + 350 -5 + 10.0 * Math.Cos(zelva.angle * Math.PI / 180.0)), (int)(350 - zelva.y -5 - 10.0 * Math.Sin(zelva.angle * Math.PI / 180.0))); g.FillEllipse(Brushes.DarkGreen,new Rectangle(pos,new Size(20,20))); g.FillEllipse(Brushes.Green,new Rectangle(phead,new Size(10,10))); g.Dispose(); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { LoadCommands(openFileDialog1.FileName); } } private void button2_Click(object sender, EventArgs e) { actStep = 0; actList = 0; zelva.x = 0; zelva.y = 0; zelva.angle = 90; zelva.r = 0; zelva.g = 0; zelva.b = 0; zelva.pen = 0; lastZelva = zelva; Graphics g = Graphics.FromImage(bmp); g.FillRectangle(Brushes.White, new Rectangle(0, 0, 700, 700)); g.Dispose(); while (actList >=0 ) { DoCommand(lists[actList].commands[actStep]); actStep += 1; while (actStep >= lists[actList].commands.Count) { if (lists[actList].rep > 1) { ComList cc = lists[actList]; cc.rep -= 1; lists[actList] = cc; actStep = 0; } else { actStep = lists[actList].returnStep + 1; actList = lists[actList].returnList; } if (actList < 0) break; } } bmp.Save("obrazek.bmp"); /* for (int i = 0; i < commands.Count; i += 1) { DoCommand(commands[i]); actStep += 1; }*/ } private void button3_Click(object sender, EventArgs e) { if (actList == -1) return; int fws = 0; while (actList >= 0) { if (DoCommand(lists[actList].commands[actStep])) { fws += 1; } actStep += 1; while (actStep >= lists[actList].commands.Count) { if (lists[actList].rep > 1) { ComList cc = lists[actList]; cc.rep -= 1; lists[actList] = cc; actStep = 0; } else { actStep = lists[actList].returnStep + 1; actList = lists[actList].returnList; } if (actList < 0) break; } if (fws >= 1) break; } totalfws += 1; DrawKrun(); } private void Form1_Activated(object sender, EventArgs e) { Graphics gg = pictureBox1.CreateGraphics(); gg.DrawImage(bmp, new Point(0, 0)); gg.Dispose(); } private void button4_Click(object sender, EventArgs e) { actStep = 0; actList = 0; zelva.x = 0; zelva.y = 0; zelva.angle = 90; zelva.r = 0; zelva.g = 0; zelva.b = 0; zelva.pen = 0; lastZelva = zelva; Graphics g = Graphics.FromImage(bmp); g.FillRectangle(Brushes.White, new Rectangle(0, 0, 700, 700)); g.Dispose(); int fws = 0; while (actList >= 0) { if (DoCommand(lists[actList].commands[actStep])) { fws += 1; } actStep += 1; while (actStep >= lists[actList].commands.Count) { if (lists[actList].rep > 1) { ComList cc = lists[actList]; cc.rep -= 1; lists[actList] = cc; actStep = 0; } else { actStep = lists[actList].returnStep + 1; actList = lists[actList].returnList; } if (actList < 0) break; } if (fws >= numericUpDown1.Value && numericUpDown1.Value != 0) break; } } private void button5_Click(object sender, EventArgs e) { if (totalfws > 0) { //v případě předchozího kroku se kreslí všechno znovu totalfws -= 1; actStep = 0; actList = 0; zelva.x = 0; zelva.y = 0; zelva.angle = 90; zelva.r = 0; zelva.g = 0; zelva.b = 0; zelva.pen = 0; lastZelva = zelva; Graphics g = Graphics.FromImage(bmp); g.FillRectangle(Brushes.White, new Rectangle(0, 0, 700, 700)); g.Dispose(); int fws = 0; while (actList >= 0) { if (DoCommand(lists[actList].commands[actStep])) { fws += 1; } actStep += 1; while (actStep >= lists[actList].commands.Count) { if (lists[actList].rep > 1) { ComList cc = lists[actList]; cc.rep -= 1; lists[actList] = cc; actStep = 0; } else { actStep = lists[actList].returnStep + 1; actList = lists[actList].returnList; } if (actList < 0) break; } if (fws == totalfws) break; } DrawKrun(); } } } }