C# 1669 chars, i implemented everything i think except msges(like laser has escpaed, laser got absorberbed etc...). ITS ALSO ANIMATED!
So its works like this, create a project called mirror and copy all of this into Form.cs.
When you press the form with your mouse it takes the variables entered into the textbox to start everything , so dont click before you enter them. The variables are as follow:
20 2 0 0 5 0 8
The first number is the grid size, the second number is the direction the laser will be going 0 is left, 1 is up, 2 is right and 3 is down. Then come the X Y starting position of the laser and after that you got 3 numbers for every object, first two being the X and Y position of the object and the third being the type of the object:
2 = /
3 = \
4 = //
5 = \\
6 = O (absorber)
7 = X (laser mirror)
8 = T (random teleport)
I dont consider my special object as worthy of the extra points since it isnt very cool. Also side note the thread doesnt finish properly so you need to kill the process (gotta save dat space). Here is a cool one to test it out
40 2 0 0 10 0 3 10 10 2 5 10 4 4 10 5 0 10 6 4 5 2 15 5 5 15 20 2 10 20 7 8 20 3 6 20 2 4 20 4 2 20 5 35 5 8
CODE
using System;using System.Collections.Generic;using System.Drawing;using System.Windows.Forms;using System.Threading;namespace mirror{partial class Form1:Form{public Form1(){InitializeComponent();this.Load+=l;}int[,]g=new int[1,1];int i;List<int[]>d=new List<int[]>();void l(object ss,EventArgs k){SetStyle(ControlStyles.AllPaintingInWmPaint,true);SetStyle(ControlStyles.OptimizedDoubleBuffer,true);this.Width=this.Height=800;TextBox t=new TextBox();this.Controls.Add(t);this.Click+=(p,e)=>{t.Hide();string[]s=t.Text.Split(' ');i=o(s[0]);g=new int[i,i];d.Add(new int[]{o(s[1]),o(s[2]),o(s[3]),0});g[d[0][1],d[0][2]]=1;for(int j=4;j<s.Length;)g[o(s[j++]),o(s[j++])]=o(s[j++]);Thread x=new Thread(r=>{while(true){for(int c=0;c<d.Count;c++){try{got:if(d[c][0]==0)d[c][1]--;if(d[c][0]==1)d[c][2]--;if(d[c][0]==2)d[c][1]++;if(d[c][0]==3)d[c][2]++;if(d[c][3]==0){int l=d[c][0];int z=g[d[c][1],d[c][2]];if(z==2)d[c][0]=l==0?3:l==1?2:l==2?1:0;if(z==3)d[c][0]=l==0?1:l==1?0:l==2?3:2;if(z==4)d.Add(new int[]{l==0?3:l==1?2:l==2?1:0,d[c][1],d[c][2],0});if(z==5)d.Add(new int[]{l==0?1:l==1?0:l==2?3:2,d[c][1],d[c][2],0});if(z==6){d.RemoveAt(c);continue;}if(z==7)d[c][3]=1;if(z==8){Random rr=new Random();d[c][1]=rr.Next(i);d[c][2]=rr.Next(i);}if(z>1)goto got;}g[d[c][1],d[c][2]]=1;}catch(Exception){}}this.Invalidate();Thread.Sleep(100);}});x.Start();};string[]ar=new string[]{" ","*","/",@"\","//",@"\\","O","X","T"};this.Paint+=(h,v)=>{Graphics z=v.Graphics;for(int q=0;q<i;q++)for (int w=0;w<i;w++){z.DrawRectangle(Pens.Black,new Rectangle(q*20,w*20,20,20));z.DrawString(ar[g[q,w]],this.Font,Brushes.Black,new Point(q*20+8,w*20+8));}};}int o(string s){return int.Parse(s);}}}
non golfed: http://pastebin.com/sNa0aK7f
Also hope you like it was fun to make! :)