<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkEMRn8yfCp7ImA9WhRRFEk.&quot;"><id>tag:blogger.com,1999:blog-5684424</id><updated>2011-11-27T16:38:07.194-08:00</updated><category term="game programming" /><category term="Battle Forces Online" /><category term="business" /><category term="press release" /><category term="AI" /><category term="rpgCardz" /><category term="stock" /><category term="marketing" /><category term="About Me" /><category term="quotes" /><category term="UntouchableGames" /><category term="Angels and Demons" /><category term="code" /><category term="lab" /><category term="ramblings" /><category term="needs followup" /><category term="BDPA" /><category term="random link" /><title>mobeamer</title><subtitle type="html">Developing, project managing and general requirement pushing</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://mobeamer.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://mobeamer.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>137</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/mobeamer" /><feedburner:info uri="mobeamer" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;C08DQ3Y-eCp7ImA9WhZbFks.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-8396967564641477820</id><published>2011-06-21T06:09:00.001-07:00</published><updated>2011-06-21T06:11:12.850-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-21T06:11:12.850-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDPA" /><category scheme="http://www.blogger.com/atom/ns#" term="About Me" /><title>About BDPA</title><content type="html">&lt;div class="WordSection1"&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;For those of you interested in knowing more about the BDPA organization, check out this great T.V. interview with its founder.&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;a href="http://vimeo.com/25390274"&gt;http://vimeo.com/25390274&lt;/a&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://player.vimeo.com/video/25390274?title=0&amp;amp;byline=0&amp;amp;portrait=0" width="400" height="225" frameborder="0"&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href="http://vimeo.com/25390274"&gt;Popular Technology TV | 2011 Pilot Episode&lt;/a&gt; from &lt;a href="http://vimeo.com/user7524555"&gt;bdpatoday&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;FYI: The National Convention is coming in August. &lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;hr /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-8396967564641477820?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/L7gWWJkfWy8Yn9yLfTi7n-Z_Pqw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/L7gWWJkfWy8Yn9yLfTi7n-Z_Pqw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/L7gWWJkfWy8Yn9yLfTi7n-Z_Pqw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/L7gWWJkfWy8Yn9yLfTi7n-Z_Pqw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/7kb9AGLciuo" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=8396967564641477820" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/8396967564641477820?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/8396967564641477820?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/7kb9AGLciuo/about-bdpa.html" title="About BDPA" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2011/06/about-bdpa.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ANQ3g5fip7ImA9WhZUEUw.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-3552771927919224936</id><published>2011-06-03T08:41:00.000-07:00</published><updated>2011-06-03T08:43:12.626-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-03T08:43:12.626-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Free Code</title><content type="html">Just a quick post..I'm slowly posting my playground work to my "lab" site.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mobeamer.com/lab"&gt;www.mobeamer.com/lab&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Consider it all open source, please provide a link back to this blog or mobeamer.com if you use in a production site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-3552771927919224936?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/F8j91N1kjAYUpRMj1PkxgBulblM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/F8j91N1kjAYUpRMj1PkxgBulblM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/F8j91N1kjAYUpRMj1PkxgBulblM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/F8j91N1kjAYUpRMj1PkxgBulblM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/_6f3-Kt3qHs" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=3552771927919224936" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/3552771927919224936?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/3552771927919224936?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/_6f3-Kt3qHs/free-code.html" title="Free Code" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2011/06/free-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQERXw4cSp7ImA9Wx9bGUQ.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-8176663849742080931</id><published>2011-02-18T10:14:00.000-08:00</published><updated>2011-03-01T08:51:44.239-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-01T08:51:44.239-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDPA" /><title>Free Training - Sign Me Up!</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-zvbLoaZ871Q/TV67T4DbZ1I/AAAAAAAAADM/RfcaFJRweH0/s1600/Bdpa-Feb-Meeting.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 373px; height: 208px;" src="http://3.bp.blogspot.com/-zvbLoaZ871Q/TV67T4DbZ1I/AAAAAAAAADM/RfcaFJRweH0/s200/Bdpa-Feb-Meeting.jpg" alt="" id="BLOGGER_PHOTO_ID_5575099338869925714" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.charlottebdpa.org/"&gt;BDPA Charlotte&lt;/a&gt; had their monthly meeting in a new location last night. We were at &lt;a href="http://www.metroteklearning.com/"&gt;Metrotek&lt;/a&gt; which is located across from Microsoft. It was one of the best meetings I've ever attended with our group.&lt;br /&gt;&lt;br /&gt;A fellow named Larry Edwards gave a presentation on Project Management and Six Sigma. How they are alike, how they are different and how they be leveraged for one another. I thought it was very informative and a good introduction into those two disciplines.&lt;br /&gt;&lt;br /&gt;A lot of great folks turned out, we had folks from Wells, Bank of America, AT&amp;amp;T and a few other companies as well.&lt;br /&gt;&lt;br /&gt;And then there was the great give-away. &lt;a href="http://www.metroteklearning.com/"&gt;Metrotek &lt;/a&gt;gave everyone in attendance access to their Microsoft Project Certification Course free of charge. They are also going to do a drawing for all those that attended and give away additional training. If that is not some great ROI on an hour spent mingling with IT folks, I'm not sure what you are looking for.&lt;br /&gt;&lt;br /&gt;For those of you who do not know, Charlotte is currently giving away $2,000,000 in training. If you are NOT employed, you need to contact Metrotek today and ask about their program. The training can be done virtually or self paced. The opportunity is knocking at your door.&lt;br /&gt;&lt;br /&gt;Oh, and there was free food. (Quizno's...I love a good sandwich).&lt;br /&gt;&lt;br /&gt;If you are in Charlotte, look us up, and join us, http://www.bdpacharlotte.org.&lt;br /&gt;&lt;br /&gt;Markus Beamer&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-8176663849742080931?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nfgq-iM9v7wu7upxLHbU6hE1oUM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nfgq-iM9v7wu7upxLHbU6hE1oUM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nfgq-iM9v7wu7upxLHbU6hE1oUM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nfgq-iM9v7wu7upxLHbU6hE1oUM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/0DoOPWvEyik" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=8176663849742080931" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/8176663849742080931?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/8176663849742080931?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/0DoOPWvEyik/free-training-sign-me-up.html" title="Free Training - Sign Me Up!" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-zvbLoaZ871Q/TV67T4DbZ1I/AAAAAAAAADM/RfcaFJRweH0/s72-c/Bdpa-Feb-Meeting.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2011/02/free-training-sign-me-up.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YFQ3szcSp7ImA9Wx9UF0Q.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-7391490180802471237</id><published>2011-02-12T07:13:00.000-08:00</published><updated>2011-02-15T09:31:52.589-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-15T09:31:52.589-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDPA" /><category scheme="http://www.blogger.com/atom/ns#" term="needs followup" /><title>Building a Pipeline of American Talent</title><content type="html">&lt;div&gt;I was sitting with some folks last week, after watching Wayne Hicks recieve &lt;a href="http://www.slideshare.net/BDPAFoundation/blacks-at-microsoft-minority-student-day-charlotte"&gt;recognition &lt;/a&gt;at the Microsoft Charlotte campus. We had a very interesting conversation which struck a cord with me. We were talking about the need to create a pipeline, a steady stream, of high quality minority talent.  Specifically for companies looking to hire this talent.&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;Now, this idea is not all mine, so I certainly won't take credit for it, but I thought I'd discuss it a bit.&lt;br /&gt;&lt;br /&gt;The realization was that, maybe, just maybe, the &lt;a href="http://www.bdpa.org/?page=Student_Programs"&gt;BDPA SITES&lt;/a&gt; program is allready setup to deliver just such a pipeline.&lt;br /&gt;&lt;br /&gt;Think about it from a hiring companies perspective. They need to find top talent for junior level technical positions. Typically they would service this need by going to College Events and other well known HR practices.&lt;br /&gt;&lt;br /&gt;But how do they find those really talented kids. The ones that have a 4.0 but also have real world experience. Those talented "Lebrauns", "Kobes" and "Shaqs" of the IT world.&lt;br /&gt;&lt;br /&gt;I know that we (BDPA) know who those students are, I personally can tick off 4 in the last two years. It's those students who have gone through our Youth Technology Camp then gone on to our "High School Computer Academy" and then followed up on our collegiate program the "IT Showcase". It's students who have had in-depth conversations and mentorship by real working IT Professionals, year after year.&lt;br /&gt;&lt;br /&gt;So when you find one of these students, you know you have found an individual who:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Excels at technology&lt;/li&gt;&lt;li&gt;Understands technology&lt;/li&gt;&lt;li&gt;Is able to develop and deliver real world solutions&lt;/li&gt;&lt;li&gt;Is capable of functioning appropriately in a company environment&lt;/li&gt;&lt;li&gt;Has excelled academically and professionally&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Put simply, these companies would find that they have a student who is ready to work and able to learn how to perform the job quicker and easier than your normal college graduate.&lt;br /&gt;&lt;br /&gt;A reliable, flexible and productive employee is a very solid ROI (Return on Investment). One might even say it is the most import measure for an HR department.  BDPA has the ability to offer those candidates on a platter.&lt;br /&gt;&lt;br /&gt;As a hiring manager, you want to get your new higher to produce as soon as possible and you want your new hire to be flexible to the nuances of your business. BDPA students deliver on both fronts.&lt;br /&gt;&lt;br /&gt;So what does BDPA ask in return, just a few things:&lt;br /&gt;&lt;br /&gt;First: Cash. It costs to get the right equipment, to market to the right youths, to give the youths experiences that will prepare them for the work force. It simply takes money.&lt;br /&gt;&lt;br /&gt;Second: Internships. You can only get experience by working. I've found that most of our students stand out as interns. Even when our &lt;span style="font-weight: bold;"&gt;high-school&lt;/span&gt; students are interning with &lt;span style="font-weight: bold;"&gt;college&lt;/span&gt; students. We encourage companies to setup high-school and college internships, both paid and unpaid, where our students can learn and contribute.&lt;br /&gt;&lt;br /&gt;Third: On the job Advancement. Once on the job, evaluate theirperformance, advance them as needed. They will shine, but you must give them opportunity to do so. Doing so will allow them to find other good employees to join your company.&lt;br /&gt;&lt;br /&gt;All in all, it was an interesting conversation. It definitely needs some polish.  I'd like to put a deck together illustrating this concept in simpler (fewer) words.&lt;br /&gt;&lt;br /&gt;But sometimes it's more important to simple capture the thought.&lt;br /&gt;&lt;br /&gt;Please keep in mind, these are my personal thoughts and opinions and not necessarily the opinions of BDPA at a national level.&lt;br /&gt;&lt;br /&gt;Thoughs? Comments?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-7391490180802471237?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/f7RD8DzeHLD1JCgVM4s0UXpuzyo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f7RD8DzeHLD1JCgVM4s0UXpuzyo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/f7RD8DzeHLD1JCgVM4s0UXpuzyo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f7RD8DzeHLD1JCgVM4s0UXpuzyo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/vSc7zmCVsU4" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=7391490180802471237" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/7391490180802471237?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/7391490180802471237?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/vSc7zmCVsU4/building-pipeline-of-american-talent.html" title="Building a Pipeline of American Talent" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2011/02/building-pipeline-of-american-talent.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MFRng-cCp7ImA9Wx9VFEU.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-2483116251681073943</id><published>2011-01-31T06:16:00.000-08:00</published><updated>2011-01-31T06:50:17.658-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-31T06:50:17.658-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ramblings" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>Technical Debt</title><content type="html">"Myrtle the Turtle told me it would take him 3 months to make my app, but Speedy Slim told me he could do it in 3 weeks? WTF?" my friend complains to me. I wince. This is not going to be easy to explain.&lt;br /&gt;&lt;br /&gt;As with most things in life, both Speedy and Turtle are right but for different reasons. At the root of it is the Technical Debt that my friend is about to signup for.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Technical Debt&lt;/span&gt; is the "cost" of &lt;span style="font-style: italic;"&gt;scaling&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;debugging &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;enhancing &lt;/span&gt;your application over its &lt;span style="font-style: italic;"&gt;lifetime&lt;/span&gt;. Minimizing these cost up-front takes time. Sometimes a lot of time. Myrtle the Turtle is all about minimizing these costs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;An analogy that most laymen will understand&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Over the entire life of your application there is a cost and the very first item that effects that cost is Speedy and Turtle. You can get this application built on cash, and pay upfront, and pay less. Or you can gt this application on credit and pay less up-front.  The choice is really yours to make.&lt;br /&gt;&lt;br /&gt;With a cash buy, you are paying every thing upfront. It's going to "hurt" more but once you get over that first build its relatively down hill from there, you will find that scaling, bugs and enhancements have a minimal cost.&lt;br /&gt;&lt;br /&gt;With credit, your paying a little up-front but it hurts less...initially. As time passes on you'll be making continue payments to the debt of this purchase. You'll find that scaling, bugs and enhancements will cost you a fair amount of money. Inevidably, you'll pay more this way then you would from a build by Turtle. &lt;span style="font-style: italic;"&gt;This is because of the interest on your technical debt.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's the cost of using Speedy and receiving a "quicker" delivery?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Speedy is going to deliver exactly what you specify&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Enhancements are going to take longer because Speedy will have to "re-work" a lot of code.&lt;/li&gt;&lt;li&gt;When more users start to use the app or more data gets into the system, the app will start to slow down and eventually will die&lt;/li&gt;&lt;li&gt;Speedy's going to get tired of working on the bad code in the app.&lt;/li&gt;&lt;li&gt;When you ask a "new" programmer to pickup the code up, you'll find that they tend to have to &lt;span style="font-weight: bold;"&gt;re-write&lt;/span&gt; the entire thing from scratch.&lt;/li&gt;&lt;/ul&gt;All of these are reasons that are not apparent in the initiall 3 to 6 months of the applications lifetime. They only become apparent down the road.&lt;br /&gt;&lt;br /&gt;I want to point out:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Even the most well built and thoughout applicaiton build can fall to the points above.&lt;/li&gt;&lt;li&gt;There are developers out there who take 6 months but still deliver the equivalent of Speedy's work.&lt;/li&gt;&lt;li&gt;It's not an easy thing to build a scalable, bug free, flexible application.&lt;/li&gt;&lt;li&gt;Scaling, Bugs and Enhancements are NEVER free in any app. It's about minimizing the cost on these items.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;When do I personally take Speedy up on his offer?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'll take Speedy over Turtle when I know that what I want is a proto-type or proof of concept. I'll take Speedy when I "have" to have something done by a given date, and there is hard dollars tied to that date. I'll take Speedy when I don't know exactly what I want built yet, but I have a vague idea.&lt;br /&gt;&lt;br /&gt;Everytime I take Speedy, I'll write down Turtle's name because I'm going to need him to build the real deal when the short need is done.&lt;br /&gt;&lt;br /&gt;Are you a Speedy Slim or a Turtle Tim? Can a developer be both "on demand"? Which developer bills higher?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-2483116251681073943?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4pufHOd6S8xtDq4CVxUrHJpOwhI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4pufHOd6S8xtDq4CVxUrHJpOwhI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4pufHOd6S8xtDq4CVxUrHJpOwhI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4pufHOd6S8xtDq4CVxUrHJpOwhI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/LOuYU1Owd-M" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=2483116251681073943" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/2483116251681073943?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/2483116251681073943?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/LOuYU1Owd-M/technical-debt.html" title="Technical Debt" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2011/01/technical-debt.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUABRXs8eCp7ImA9Wx9VFkg.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-7734653203100105987</id><published>2011-01-27T12:00:00.000-08:00</published><updated>2011-02-02T06:42:34.570-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-02T06:42:34.570-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AI" /><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><title>More about Jarvis the Chat Bot</title><content type="html">I mentioned that I created a chat bot named Jarvis. Since then I've been asked a few times what goes into creating Jarvis. I thought I'd take the time and explain what is going on behind the scenes.&lt;br /&gt;&lt;br /&gt;First off Jarvis sits on top of database with the following tables.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;word - A library of known words he found online&lt;/li&gt;&lt;li&gt;keywords - collections of words that Jarvis thought went together&lt;/li&gt;&lt;li&gt;responses - Response that can be given to a user&lt;/li&gt;&lt;/ul&gt;There are other tables, but that is the core ones.&lt;br /&gt;&lt;br /&gt;Now I loaded Jarvis with the library that ELIZA the original chat bot used. That system had a number of keywords and responses to those key words. For example: If the user had typed "Hi", there were 3 possible responses. "How are you?", "Hello", "Welcome".&lt;br /&gt;&lt;br /&gt;Jarvis would randomly pick one of those.&lt;br /&gt;&lt;br /&gt;I also hand entered in some other "choice" keywords and phrases.&lt;br /&gt;&lt;br /&gt;The next step was to have him learn from input. So when ever Jarvis puts out a response that includes a question (question mark), he would wait for the response and tag it as a possible "answer" to that question. That way when another user asked the question of Jarvis this was in his possible responses.&lt;br /&gt;&lt;br /&gt;So for example, Jarvis might start off with a memory like the following:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Key: How are you?&lt;br /&gt;Possible Responses: "Good", "I'm sad" or "I'm happy".&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;Let's say he had the following conversation with user 1.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Jarvis: Hi&lt;br /&gt;User 1: Hello Jarvis&lt;br /&gt;Jarvis: How are you?&lt;br /&gt;User 1: I'm good, I had bacon this morning.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Now Jarvis' memory looks like the following:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Key: How are you?&lt;br /&gt;Possible Responses: "Good", "I'm sad" or "I'm happy" or "I'm good, I had bacon this morning"&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So when user 3 comes along the conversation looks like this...&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Jarvis: Hello&lt;br /&gt;User 3: Hi Jarvis, How are you?&lt;br /&gt;Jarvis: I'm good, I had bacon this morning&lt;br /&gt;User 3: That sounds good&lt;br /&gt;Jarvis: how are you?&lt;br /&gt;User 3: Hungry&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Jarvis used the first users answers and he also learned a new answer to the question "How are you?"&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Key: How are you?&lt;br /&gt;Possible Responses: "Good", "I'm sad" or "I'm happy" or "I'm good, I had bacon this morning", "Hungry"&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Curiosity&lt;/span&gt;&lt;br /&gt;At first I built him so that any response that was a question was given priority. But that lead to Jarvis asking to many questions. So Jarvis now has a curiosity factor. The more curious he is, the more likey that he will give a response that is in the form of a question. This sponsors more responses for him.&lt;br /&gt;&lt;br /&gt;You can increase or decrease curiosity by typing "moreCurious" or "lessCurious" into the text box.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Peeking into Jarvis Brain&lt;/span&gt;&lt;br /&gt;There is a checkbox "Peek into Brain". Clicking this will let you see into Jarvis process. It shows you the following:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Words gathered from your input&lt;/li&gt;&lt;li&gt;Last 5 words learned (popularity is in parens)&lt;/li&gt;&lt;li&gt;The Keywords or phrases that were triggered based on your words&lt;/li&gt;&lt;li&gt;Selected/Best Keyword is highlights in bold&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The Responses triggered from the best keyword&lt;/li&gt;&lt;li&gt;The last 5 learned keyword phrases&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The last 5 learned responses&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Scoreing&lt;/span&gt;&lt;br /&gt;Jarvis tracks each chat session and gives it a score. Keep in mind each possible response is scored. Anytime Jarvis uses an response with a score higher than 0, he adds one to the session score.&lt;br /&gt;&lt;br /&gt;This should lead to interesting sessions having a higher score, but I have not thoroughly tested that.&lt;br /&gt;&lt;br /&gt;Jarvis can be found at &lt;a href="http://www.mobeamer.com/lab/jarvis"&gt;http://www.mobeamer.com/lab/jarvis&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Randomness&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are two places where Jarvis uses randomness.&lt;br /&gt;&lt;br /&gt;First: Sometimes after finding all the keyphrases from the users input. Multiple keypharases have the same score. In this case, Jarvis will randomly select one of them.&lt;br /&gt;&lt;br /&gt;Second: Sometimes after finding all responses from a keyphrase, mulitple responses have the same score. In this case, Jarvis will randomly select one.&lt;br /&gt;&lt;br /&gt;The random function uses php's in-built rand() function. Which is not 100% random but close enough for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-7734653203100105987?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ii3quuaByT6tcokFNFWnKWlSYDs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ii3quuaByT6tcokFNFWnKWlSYDs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ii3quuaByT6tcokFNFWnKWlSYDs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ii3quuaByT6tcokFNFWnKWlSYDs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/AEbG4KQapbo" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=7734653203100105987" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/7734653203100105987?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/7734653203100105987?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/AEbG4KQapbo/more-about-jarvis-chat-bot.html" title="More about Jarvis the Chat Bot" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2011/01/more-about-jarvis-chat-bot.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkYNRXg6eip7ImA9Wx9WGEQ.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-4922721058189966764</id><published>2011-01-24T10:28:00.000-08:00</published><updated>2011-01-24T10:36:34.612-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-24T10:36:34.612-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AI" /><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="lab" /><title>Jarvis - A chatterbot</title><content type="html">If you didn't know AI (artificial intelligence) has become a bit of a hobby of mine. In an effort to explore the domain, I thought that I would throw together a little chat bot.&lt;br /&gt;&lt;br /&gt;He's based off of the original chat bot, ELIZA.&lt;br /&gt;&lt;br /&gt;I have/had a lot of thoughts of the direction I could take this in, but I wanted to get a version 1.0 all wrapped up and released before taking on other challenges.&lt;br /&gt;&lt;br /&gt;You can chat with Jarvis at:&lt;a href="http://www.mobeamer.com/lab/jarvis/"&gt; www.mobeamer.com/lab/jarvis/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Some fun facts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Jarvis was named after the AI in Iron Man&lt;/li&gt;&lt;li&gt;My 11 year old son, taught Jarvis a few key sayings&lt;/li&gt;&lt;li&gt;Sometimes Jarvis is incredibly stupid&lt;/li&gt;&lt;li&gt;Jarvis has a fully built out relationship model for words, key phrases and responses.&lt;/li&gt;&lt;li&gt;Jarvis can learn from chatting with other users&lt;/li&gt;&lt;/ul&gt;Some thoughts on what to implement next:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Allow Jarvis to "read" or learn from websites (Wikipedia)&lt;/li&gt;&lt;li&gt;Allow Jarvis to formulate higher "concepts" where responses are all connected via a single word or key phrase.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Allows users to chat with other users and Jarvis at the same time and ask them to spot Jarvis in the crowd&lt;/li&gt;&lt;li&gt;Allow Jarvis to get happier the longer someone chats with him&lt;/li&gt;&lt;li&gt;Add some type of visual representation of Jarvis&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-4922721058189966764?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CyehgGwll4gsw0NYwgIgSOxwsn0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CyehgGwll4gsw0NYwgIgSOxwsn0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CyehgGwll4gsw0NYwgIgSOxwsn0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CyehgGwll4gsw0NYwgIgSOxwsn0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/PYUwk7g0vM0" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=4922721058189966764" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/4922721058189966764?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/4922721058189966764?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/PYUwk7g0vM0/jarvis-chatterbot.html" title="Jarvis - A chatterbot" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2011/01/jarvis-chatterbot.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8FR347cCp7ImA9Wx9WFk8.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-1613350141512277725</id><published>2011-01-21T07:21:00.000-08:00</published><updated>2011-01-21T07:30:16.008-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-21T07:30:16.008-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDPA" /><category scheme="http://www.blogger.com/atom/ns#" term="ramblings" /><title>Charlotte BDPA - 2011 Kickoff</title><content type="html">We had the Charlotte BDPA 2011 kickoff meeting last night. I think it went very well. A little recap of what I remember off the top of my head.:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Diondre, with IBN Consulting, is interested in teaching folks a number of IT topics, his business has an office downtown and has been training folks for a few months now. Definitely want to keep in touch with this guy.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sheila (spl?) - The Urban League has a new program, they are giving CISCO certifications to 11th and 12th graders. The programs are held at Phillip O'Berry. Sounds like there are some nice perks with the program as well. (Laptop, software and such). She needs IT professionals to come by and speak about the career. I told her to count me in. If you know of anyone or are interested, reach out to me.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;2 BDPA members recently moved to new roles within thier current companies. You know I love to hear news like this.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Charlotte BDPA 2011 calendar is full of education and training opportunities for adult professionals. A bit of a change in focus for our chapter but a refreshing one.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Charles - With APEX has a few development, PM and BA job opportunities for anyone who is looking.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;All in all, it was a good meeting and better networking.  I'm looking forward to our next meeting in Feb.&lt;br /&gt;&lt;br /&gt;Hope you are starting the year off right.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-1613350141512277725?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ke9fX0Y5VhDEVARt6jzvgS9hZ_Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ke9fX0Y5VhDEVARt6jzvgS9hZ_Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ke9fX0Y5VhDEVARt6jzvgS9hZ_Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ke9fX0Y5VhDEVARt6jzvgS9hZ_Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/rkrgTnsnY-A" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=1613350141512277725" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/1613350141512277725?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/1613350141512277725?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/rkrgTnsnY-A/charlotte-bdpa-2011-kickoff.html" title="Charlotte BDPA - 2011 Kickoff" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2011/01/charlotte-bdpa-2011-kickoff.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4DSHk-eyp7ImA9WxFaEU8.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-9138832710982676586</id><published>2010-07-14T10:02:00.001-07:00</published><updated>2010-07-14T10:02:59.753-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-14T10:02:59.753-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="About Me" /><title>5 Ways to be Lucky and Successful</title><content type="html">Quite often I find myself talking about these rules during our weekly programming training classes (&lt;a href="http://www.bdpa-charlotte.org/"&gt;BDPA - HSCC&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Luck and success is all around you. But you have to be open to it. There is a mindset to being lucky and being successful. The following are some rules that help me to be lucky and successful:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Rule 1. Roll with the Changes&lt;/span&gt;&lt;br /&gt;Change is going to come. We all make plans and life promptly crushes them. But when everything is falling apart, take the time to look around. Somewhere in the madness is an opportunity.&lt;br /&gt;&lt;br /&gt;Grab it, catch it, put it in your back pocket, clean up your life, get back on track, then pull the opportunity out of your pocket and explore it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Rule 2. Walk with open eyes&lt;br /&gt;&lt;/span&gt;The simple act of noticing will bring luck to you. We don't always have to rush.  Take the time to stroll and look around. You never know...&lt;br /&gt;See that lady with the screaming four year old? She might have the job you've been looking for. Maybe you should have stopped and helped her.&lt;br /&gt;&lt;br /&gt;Did you see that billboard about the master's degree? They might have a grant with your name on it.&lt;br /&gt;&lt;br /&gt;See that flyer on the wall, don't you recognize that face? It's an old co-worker looking for a partner to start their next business.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3. Be Bold&lt;/span&gt;&lt;br /&gt;Take risk, you don't have as much to lose as you think. Really has rejection ever killed anyone. Put yourself out there, so someone can pick you up. Keep in mind that if you let yourself, you will talk yourself out of everything that was meant for you. &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4. Know when to quit&lt;/span&gt;&lt;br /&gt;Because you are now taking risks and being bold, you will find a lot of things going on in your life. This is good, you're enjoying life. But at some point it will be too much. I know when I reach this point because I start to habitually avoid doing things. So, the time has come to trim to fat and let something go. Choose carefully, but admit and realize that &lt;span style="font-style: italic;"&gt;something &lt;/span&gt;has to go.&lt;br /&gt;&lt;br /&gt;On the other hand, be honest about your efforts are they profitable, monetarily or emotionally. If you ain't getting no satisfaction its a good sign that it's time to cut it loose. Life is to short to spend it on the un-enjoyable.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5. Make "me" time&lt;/span&gt;&lt;br /&gt;Leave time to do nothing. I repeat nothing. Pretend that you're going to sit on your butt and do...wait for it...nothing. You'll find that this is the most enjoyable time you have. You will look forward to this time. You will crave it. The day just won't seem right without it. Why?&lt;br /&gt;&lt;br /&gt;Because your nothing time turns into the time you do the thing you absolutely 100% enjoy doing above anything else. You have no obligations, you can do anything you want. You will naturally do what you like the most. Surprisingly you will find that this activity will change week to week. Your brain's appetite is large, once you allow it to join the buffet.&lt;br /&gt;&lt;br /&gt;Now, don't go crazy, you can't have "me" time all of the time. Then the pleasure of it goes away, not to mention that the rest of your life will go sideways on you.&lt;br /&gt;&lt;br /&gt;So there you have it. 5 simple rules that I live by. They help me be lucky and successful,. They can definitely help you.&lt;br /&gt;&lt;br /&gt;What rules would you add?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-9138832710982676586?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ER8JJ9h2vQ4Hee3Pd6VeiSlnz1A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ER8JJ9h2vQ4Hee3Pd6VeiSlnz1A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ER8JJ9h2vQ4Hee3Pd6VeiSlnz1A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ER8JJ9h2vQ4Hee3Pd6VeiSlnz1A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/y23rqvsYupc" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=9138832710982676586" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/9138832710982676586?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/9138832710982676586?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/y23rqvsYupc/5-ways-to-be-lucky-and-successful.html" title="5 Ways to be Lucky and Successful" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/07/5-ways-to-be-lucky-and-successful.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8FRnkyeCp7ImA9WxFbGUk.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-235113311068765980</id><published>2010-07-12T08:14:00.000-07:00</published><updated>2010-07-12T08:16:57.790-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-12T08:16:57.790-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDPA" /><category scheme="http://www.blogger.com/atom/ns#" term="lab" /><title>Intro to Data Warehouses</title><content type="html">This is a recent presentation I gave on data marts and data warehousing techniques. This only scratches the surface and there are a loot of places to dive deeper.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="View Date Warehousing on Scribd" href="http://www.scribd.com/doc/34218825/Date-Warehousing" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;Date Warehousing&lt;/a&gt; &lt;object id="doc_178306977632725" name="doc_178306977632725" height="500" width="100%" type="application/x-shockwave-flash" data="http://d1.scribdassets.com/ScribdViewer.swf" style="outline:none;" &gt;  &lt;param name="movie" value="http://d1.scribdassets.com/ScribdViewer.swf"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="FlashVars" value="document_id=34218825&amp;access_key=key-26bvlt840cychdmcvc6s&amp;page=1&amp;viewMode=list"&gt;   &lt;embed id="doc_178306977632725" name="doc_178306977632725" src="http://d1.scribdassets.com/ScribdViewer.swf?document_id=34218825&amp;access_key=key-26bvlt840cychdmcvc6s&amp;page=1&amp;viewMode=list" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="500" width="100%" wmode="opaque" bgcolor="#ffffff"&gt;&lt;/embed&gt;  &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-235113311068765980?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/t9yUWpr431PO7jHv-LdQ9dWmURM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t9yUWpr431PO7jHv-LdQ9dWmURM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/t9yUWpr431PO7jHv-LdQ9dWmURM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t9yUWpr431PO7jHv-LdQ9dWmURM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/wwgkLimnAmA" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=235113311068765980" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/235113311068765980?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/235113311068765980?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/wwgkLimnAmA/intro-to-data-warehouses.html" title="Intro to Data Warehouses" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/07/intro-to-data-warehouses.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIERXk-cCp7ImA9WxFXEU0.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-1385867067058781780</id><published>2010-05-17T06:48:00.000-07:00</published><updated>2010-05-17T07:28:24.758-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-17T07:28:24.758-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>5 min Intro to PHP</title><content type="html">If your interested in learning or playing with PHP. Here is a short introduction to get you started. I expect that you have some basic programming skills already. (or the will power to stay and play for a while)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Download It&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If your using a window OS you will want an "XAMP" installation. It installs Apache, PHP and MySQL on windows. Most of them are simple: download, unzip and click the "start" executable. I like to use &lt;a href="http://www.uniformserver.com/"&gt;Uniform Server&lt;/a&gt;. I won't go into debugging apache in this article, but I will suggest that you shut off any program that uses the web server ports.  (Visual Studio, IIS, Skype).&lt;br /&gt;&lt;br /&gt;Alternatively you can play on any website you have, most will have php enabled.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Basic Things to know&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Save your page with a .php extension&lt;/li&gt;&lt;li&gt;Surround your code with  &amp;lt;?php ...code....  ?&amp;gt;&lt;/li&gt;&lt;li&gt;You can use  &amp;lt;? ...code....  ?&amp;gt; but that is non-standards compliant&lt;/li&gt;&lt;li&gt;All statements in php must end with ";"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Variables start with $. IE: $username, $today, $yesterday, $i&lt;/li&gt;&lt;li&gt;Variables "live" to the end of page, but do not carry over into functions&lt;/li&gt;&lt;li&gt;Single line comments use //&lt;/li&gt;&lt;li&gt;Multi line comments use /* .... */&lt;/li&gt;&lt;li&gt;To add strings use "." (IE:  $firstName . " " .  $lastName)&lt;/li&gt;&lt;li&gt;To add numbers use "+" (IE: $age + 10)&lt;/li&gt;&lt;li&gt;Use print to print  (IE: print "Hello " . $username)&lt;/li&gt;&lt;li&gt;Use echo to print   (IE: echo "Hello " . $username)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;If statements&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;if( boolean )&lt;br /&gt;{&lt;br /&gt;//...some code&lt;br /&gt;}&lt;br /&gt;elseif( boolean )&lt;br /&gt;{&lt;br /&gt;//...some code&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;//...other code&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Loops&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;for($i=0;$i&amp;lt;10;$i++)&lt;br /&gt;{&lt;br /&gt;    //...code&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;while( boolean )&lt;br /&gt;{&lt;br /&gt;    // ...code&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Variables, Sessions and Forms&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Normal Variable: $username;&lt;br /&gt;Session Variable: $_SESSION["username"]&lt;br /&gt;Form Post Variable: $_POST["username"]&lt;br /&gt;Form Get Variable: $_GET["username"]&lt;br /&gt;&lt;br /&gt;Kill a session variable: $_SESSION["username"] = "";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Database&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;PHP normally uses mySQL, but each of the functions below have an equivalent function for most database systems.&lt;br /&gt;&lt;br /&gt;$db_host = "localhost";&lt;br /&gt;$db_user = "user";&lt;br /&gt;$database = "dbname";&lt;br /&gt;$db_passwd = "pass";&lt;br /&gt;mysql_connect($db_host, $db_user, $db_passwd);&lt;br /&gt;$q = mysql_query("select * from user");&lt;br /&gt;&lt;br /&gt;while($row = mysql_fetch_object($q))&lt;br /&gt;{&lt;br /&gt;print $row-&gt;username;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Alternativly you can use mysql_fetch_row($q)...this will get an array of the field values and you can access them by $row[0], $row[1]....etc.&lt;br /&gt;&lt;br /&gt;As with most high level languages, php has a number of functions available to it. You can search the very friendly documentation at www.php.net&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Objects and Classes&lt;/span&gt;&lt;br /&gt;Class DateUtils&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;function DateUtils()&lt;br /&gt;{&lt;br /&gt;    //...constructor&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function getToday($format)&lt;br /&gt;{&lt;br /&gt;      return date($format);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;And here is how to use the class&lt;br /&gt;&lt;br /&gt;$util = new DateUtils();&lt;br /&gt;print $utils-&gt;getToday();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;What else would you like to know?&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-1385867067058781780?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VE0oY0h8ysChaFTaTRC1oemctZQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VE0oY0h8ysChaFTaTRC1oemctZQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/VE0oY0h8ysChaFTaTRC1oemctZQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VE0oY0h8ysChaFTaTRC1oemctZQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/QL6Za-5pQus" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=1385867067058781780" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/1385867067058781780?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/1385867067058781780?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/QL6Za-5pQus/5-min-intro-to-php.html" title="5 min Intro to PHP" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/05/5-min-intro-to-php.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMNR3s-fCp7ImA9WxFQFUw.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-8058689281757284833</id><published>2010-04-26T06:56:00.001-07:00</published><updated>2010-05-10T11:34:56.554-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-10T11:34:56.554-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>CSS: Tabbed Menu</title><content type="html">Free Code. This comes directly from this site &lt;a href="http://www.webcredible.co.uk/user-friendly-resources/css/css-round-corners.shtml"&gt;http://www.webcredible.co.uk/user-friendly-resources/css/css-round-corners.shtml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Creates rounded menus.&lt;br /&gt;&lt;br /&gt;You will need the following four images:&lt;br /&gt;&lt;li&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S9Wb7d4Y_OI/AAAAAAAAACk/RudUd7C2PoM/s1600/right-tab.gif"&gt;&lt;img style="cursor: pointer; width: 7px; height: 19px;" src="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S9Wb7d4Y_OI/AAAAAAAAACk/RudUd7C2PoM/s400/right-tab.gif" alt="" id="BLOGGER_PHOTO_ID_5464445168819698914" border="0" /&gt;&lt;/a&gt; - Right Tab&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_MXZ6aBwP4Wo/S9Wb2ctl4OI/AAAAAAAAACc/990o0WpHs2w/s1600/left-tab.gif"&gt;&lt;img style="cursor: pointer; width: 7px; height: 19px;" src="http://2.bp.blogspot.com/_MXZ6aBwP4Wo/S9Wb2ctl4OI/AAAAAAAAACc/990o0WpHs2w/s400/left-tab.gif" alt="" id="BLOGGER_PHOTO_ID_5464445082606624994" border="0" /&gt;&lt;/a&gt; Left Tab&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_MXZ6aBwP4Wo/S9WcCzSXFbI/AAAAAAAAAC0/n-1MBYUOI28/s1600/right-tab-hover.gif"&gt;&lt;img style="cursor: pointer; width: 7px; height: 19px;" src="http://2.bp.blogspot.com/_MXZ6aBwP4Wo/S9WcCzSXFbI/AAAAAAAAAC0/n-1MBYUOI28/s400/right-tab-hover.gif" alt="" id="BLOGGER_PHOTO_ID_5464445294824854962" border="0" /&gt;&lt;/a&gt; Right Tab Hover&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S9WcCozH18I/AAAAAAAAACs/gXzfj8owZxw/s1600/left-tab-hover.gif"&gt;&lt;img style="cursor: pointer; width: 7px; height: 19px;" src="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S9WcCozH18I/AAAAAAAAACs/gXzfj8owZxw/s400/left-tab-hover.gif" alt="" id="BLOGGER_PHOTO_ID_5464445292009478082" border="0" /&gt;&lt;/a&gt; Left Tab Hover&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Code&lt;/b&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;style&amp;gt;&lt;br /&gt;  #navigation a&lt;br /&gt;  {&lt;br /&gt;  color: #000;&lt;br /&gt;  background: #ffa20c url(left-tab.gif) left top no-repeat;&lt;br /&gt;  text-decoration: none;&lt;br /&gt;  padding-left: 10px&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  #navigation a span&lt;br /&gt;  {&lt;br /&gt;  background: url(right-tab.gif) right top no-repeat;&lt;br /&gt;  padding-right: 10px&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  #navigation a, #navigation a span&lt;br /&gt;  {&lt;br /&gt;  display: block;&lt;br /&gt;  float: left&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /* Hide from IE5-Mac \*/&lt;br /&gt;  #navigation a, #navigation a span&lt;br /&gt;  {&lt;br /&gt;  float: none&lt;br /&gt;  }&lt;br /&gt;  /* End hide */&lt;br /&gt;&lt;br /&gt;  #navigation a:hover&lt;br /&gt;  {&lt;br /&gt;  color: #fff;&lt;br /&gt;  background: #781351 url(left-tab-hover.gif) left top no-repeat;&lt;br /&gt;  padding-left: 10px&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  #navigation a:hover span&lt;br /&gt;  {&lt;br /&gt;  background: url(right-tab-hover.gif) right top no-repeat;&lt;br /&gt;  padding-right: 10px&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  #navigation ul&lt;br /&gt;  {&lt;br /&gt;  list-style: none;&lt;br /&gt;  padding: 0;&lt;br /&gt;  margin: 0&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  #navigation li&lt;br /&gt;  {&lt;br /&gt;  list-style: none;&lt;br /&gt;  float: left;&lt;br /&gt;  margin: 0;&lt;br /&gt;  }&lt;br /&gt; &amp;lt;/style&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;h1&amp;gt;Tabbed Menu Test&amp;lt;/h1&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;ul id=&amp;quot;navigation&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Home&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Services&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Take a tour&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;&amp;lt;span&amp;gt;About us&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Contact us&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-8058689281757284833?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DMEh6KjIx9GglwIVNo3VZrHarPU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DMEh6KjIx9GglwIVNo3VZrHarPU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DMEh6KjIx9GglwIVNo3VZrHarPU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DMEh6KjIx9GglwIVNo3VZrHarPU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/0e8JdnIksjg" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=8058689281757284833" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/8058689281757284833?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/8058689281757284833?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/0e8JdnIksjg/css-tabbed-menu.html" title="CSS: Tabbed Menu" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S9Wb7d4Y_OI/AAAAAAAAACk/RudUd7C2PoM/s72-c/right-tab.gif" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/04/css-tabbed-menu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkABRHY_fSp7ImA9WxFRFEs.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-6337144287217914756</id><published>2010-04-23T07:33:00.000-07:00</published><updated>2010-04-28T07:25:55.845-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-28T07:25:55.845-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Javascript - 2D Map Library</title><content type="html">This article is a wrap up of a series of articles in which I walk through building a simple 2d top down map library. Below are the articles that build this library:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://mobeamer.blogspot.com/2010/03/code-simple-2d-javascript-map.html"&gt;Part 1: Drawing the Map&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-2.html"&gt;Part 2: Clicking a tile&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-3.html"&gt;Part 3: Adding a Unit&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-4.html"&gt;Part 4: Moving the Unit&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-5.html"&gt;Part 5: Creating Enemies&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-6.html"&gt;Part 6: Score Keeping&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mobeamer.blogspot.com/2010/04/javascript-2d-map-library.html"&gt;Part 7: Final Library&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;For those of you that want the code, scroll past the explanations, it's at the bottom.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Style.css. &lt;/span&gt;&lt;br /&gt;While testing and playing I usually will include the style in one page, for the ease of editing, but it's always a good idea to separate the style sheet from the main body of code. This allows an artist to come along and play with the look and feel of the site without screwing with your brilliantly created code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Map.js.&lt;/span&gt;&lt;br /&gt;All the general re-usable functions for mapping. If you ever finish coding a function and think, man I'll never have to touch this again, its so perfect and I'll use it all the time! First, slap yourself, cause we all know it's going to have a bug in it at some time. Second realize that the function in question, is prime material to go into a library of sorts. The functions in map.js are generic and can be kept from game to game as you build different things. At least that is my hope.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;TileClicked()&lt;/span&gt;&lt;br /&gt;I left tile clicked in the main body of the page because the actions you might want to take when a tile is clicked will change from game to game. Thus it is not library material.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;DestReached()&lt;/span&gt;&lt;br /&gt;This is a new function that was not discussed in other articles. Once a unit is done moving to it's destination of location, this function is called. I figured game builders might want to change this function depending on the game.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Play()&lt;/span&gt;&lt;br /&gt;This is the heart of your game, if you want enemies to run around randomly, here is where you put that stuff. This function will call itself every few milliseconds, the more code in this function the slower your game is going to run.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ObjectsCollided()&lt;/span&gt;&lt;br /&gt;This function is called when ever two units combine. The unit that moved last and did the collision is passed along with the id of each unit that is involved in the collision. You'll want to customize this function.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Body Tag&lt;/span&gt;&lt;br /&gt;The body tag calls the buildMap and addUnit function. I'd expect that you will want to change that.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Div Elements&lt;/span&gt;&lt;br /&gt;There are two divs in the html one to hold the map and another to hold the score. You can move those around, but they must be somewhere in the page for the library to work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Map.js Function List&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;BuildMap(width, height)&lt;/span&gt;&lt;br /&gt;Builds a map of width and height. It will also add walls to all edges of the map, so units don't wonder off it. Comment out the "addBorders()" line if you don't want this.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;AddBorders()&lt;/span&gt;&lt;br /&gt;Ummm, it adds borders...nuff said&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;addWall(x,y)&lt;/span&gt;&lt;br /&gt;Turns tile x,y into a wall. Sets tile's flag = -1, sets the background color&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;addUnit(unitID, x, y)&lt;/span&gt;&lt;br /&gt;Adds a unit with that ID to the map at &lt;span style="font-weight: bold;"&gt;tile &lt;/span&gt;location x, y. Multiple units can be added. If unitID is 1000 it is given the css class "unit". Otherwise the class is "enemy"&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;setWalkableFlag(x, y, flag)&lt;/span&gt;&lt;br /&gt;Sets tile x, y "flag" variable to the flag passed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;jumpUnit(unitID, tileDestX, tileDestY)&lt;/span&gt;&lt;br /&gt;Moves a unit directly to that tile, no animation at all...unit just jumps to location.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;move(unitID, dir)&lt;/span&gt;&lt;br /&gt;Move a unit &lt;span style="font-weight: bold;"&gt;one &lt;/span&gt;tile in the direction specified. Valid directions are N, E, S, W. This is an animated move (one pixel at a time). This uses the moveUnit() function.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;moveUnit(unitID, tileDestX, tileDestY)&lt;/span&gt;&lt;br /&gt;Moves a unit to the tile passed in. If at anytime the unit hits a none walkable tile, the unit will move back to last position. (no route finding). Calls DestReached() when completed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;isWalkable(x,y)&lt;/span&gt;&lt;br /&gt;Returns "Y" or "N" if &lt;span style="font-weight: bold;"&gt;pixel &lt;/span&gt;x, y is walkable&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;isWalkableTile(x,y)&lt;/span&gt;&lt;br /&gt;Returns "Y" or "N" if &lt;span style="font-weight: bold;"&gt;tile &lt;/span&gt;x, y is walkable&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;getTop(obj)&lt;/span&gt;&lt;br /&gt;Return the top pixel (y) of the object. Could use some optimization&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;getLeft(obj)&lt;/span&gt;&lt;br /&gt;Return the left pixel (x) of the object. Could use some optimization&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;translateTileX(x), translateTileY(y)&lt;/span&gt;&lt;br /&gt;return the tileX that pixel x is located within&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;getTileX(unitID), getTileY(unitID)&lt;/span&gt;&lt;br /&gt;return the tile x and tile y that the unit is located on&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Here be code!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Style Sheet (style.css)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;.tile {&lt;br /&gt;background:#BBB;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.unit {&lt;br /&gt;background:green;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.enemy {&lt;br /&gt;background:red;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.food {&lt;br /&gt;background:black;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Map.js (the library)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&lt;br /&gt;var originX = 0;&lt;br /&gt;var originY = 0;&lt;br /&gt;var tileSize = 16;&lt;br /&gt;var mapHeight = 0;&lt;br /&gt;var mapWidth =0;&lt;br /&gt;var score=0;&lt;br /&gt;var playSpeed = 1000;&lt;br /&gt;var numUnits = 0;&lt;br /&gt;var maxNumUnits = 40;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function buildMap(width, height)&lt;br /&gt;{&lt;br /&gt;mapHeight = height;&lt;br /&gt;mapWidth = width;&lt;br /&gt;&lt;br /&gt;for(x=0;x&amp;lt;width;x++)&lt;br /&gt;for(y=0;y&amp;lt;height;y++)&lt;br /&gt;{&lt;br /&gt;var d = document.createElement("DIV");&lt;br /&gt;d.className="tile";&lt;br /&gt;d.setAttribute("ID","tile_" + x + "_" + y);&lt;br /&gt;d.style.top = originY + (y*tileSize);&lt;br /&gt;d.style.left = originX + (x*tileSize);&lt;br /&gt;d.style.width = tileSize;&lt;br /&gt;d.style.height = tileSize;&lt;br /&gt;d.setAttribute("flag","0");&lt;br /&gt;d.setAttribute("onclick","tileClicked(" + x + "," + y + ")")&lt;br /&gt;document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;addBorders();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function addBorders()&lt;br /&gt;{&lt;br /&gt;for(x=0;x&amp;lt;mapWidth;x++)&lt;br /&gt;{&lt;br /&gt; addWall(x, 0);&lt;br /&gt; addWall(x, mapHeight-1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;for(y=0;y&amp;lt;mapHeight;y++)&lt;br /&gt;{&lt;br /&gt; addWall(0, y);&lt;br /&gt; addWall(mapWidth-1,y);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function addWall(x,y)&lt;br /&gt;{&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; tile.setAttribute("flag","-1");&lt;br /&gt; tile.style.background = "#777"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function addUnit(unitID, x,y)&lt;br /&gt;{&lt;br /&gt; var d = document.createElement("DIV");&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; if(unitID == 1000)&lt;br /&gt; {&lt;br /&gt;  d.className="unit";&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  d.className="enemy";&lt;br /&gt; }&lt;br /&gt; d.setAttribute("xVel", 0);&lt;br /&gt; d.setAttribute("yVel", 0);&lt;br /&gt; d.setAttribute("ID","unit_" + unitID);&lt;br /&gt; d.style.top = tile.style.top;&lt;br /&gt; d.style.left = tile.style.left;&lt;br /&gt; d.style.width = tileSize;&lt;br /&gt; d.style.height = tileSize;&lt;br /&gt; d.setAttribute("currTileX",x);&lt;br /&gt; d.setAttribute("currTileY",y);&lt;br /&gt; d.setAttribute("priorTileX",x);&lt;br /&gt; d.setAttribute("priorTileY",y);&lt;br /&gt;&lt;br /&gt; setWalkableFlag(x, y, unitID);&lt;br /&gt;&lt;br /&gt; document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function setWalkableFlag(x, y, flag)&lt;br /&gt;{&lt;br /&gt; var tmpTile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; tmpTile.setAttribute("flag", flag);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function jumpUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; unit.style.left = getLeft(tile);&lt;br /&gt; unit.style.top = getTop(tile);&lt;br /&gt; //&lt;br /&gt; //mark the current tile as UNwalkable&lt;br /&gt; //&lt;br /&gt; setWalkableFlag(unit.getAttribute("currTileX"), unit.getAttribute("currTileY"), "0");&lt;br /&gt;&lt;br /&gt; //&lt;br /&gt; //mark the old tile as WALKABLE&lt;br /&gt; //&lt;br /&gt; setWalkableFlag(unit.getAttribute("priorTileX"), unit.getAttribute("priorTileY"), "0");&lt;br /&gt;&lt;br /&gt; unit.setAttribute("currTileX",x);&lt;br /&gt; unit.setAttribute("currTileY",y);&lt;br /&gt; unit.setAttribute("priorTileX",x);&lt;br /&gt; unit.setAttribute("priorTileY",y);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function move(unitID, dir)&lt;br /&gt;{&lt;br /&gt; x = getTileX(unitID)&lt;br /&gt; y = getTileY(unitID)&lt;br /&gt; &lt;br /&gt; if(dir == "N")&lt;br /&gt; {&lt;br /&gt;  y--;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; if(dir == "E")&lt;br /&gt; {&lt;br /&gt;  x++;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; if(dir == "S")&lt;br /&gt; {&lt;br /&gt;  y++;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; if(dir == "W")&lt;br /&gt; {&lt;br /&gt;  x--;&lt;br /&gt; } &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; if(isWalkableTile(x, y) == "Y")&lt;br /&gt; {&lt;br /&gt;  moveUnit(unitID, x, y);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function moveUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; unit.setAttribute("priorTileX",getTileX(unitID));&lt;br /&gt; unit.setAttribute("priorTileY",getTileY(unitID));&lt;br /&gt;&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  alert("no tile found");&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; x = getLeft(unit);&lt;br /&gt; y = getTop(unit);&lt;br /&gt; destX = getLeft(tile);&lt;br /&gt; destY = getTop(tile);&lt;br /&gt; newX = x;&lt;br /&gt; newY = y;&lt;br /&gt;&lt;br /&gt; if(x &amp;gt; destX) newX--;&lt;br /&gt; if(x &amp;lt; destX) newX++;&lt;br /&gt; if(y &amp;gt; destY) newY--;&lt;br /&gt; if(y &amp;lt; destY) newY++;&lt;br /&gt;&lt;br /&gt; if(isWalkable(newX, newY) == "Y" &amp;amp;&amp;amp; isWalkable(newX+tileSize-2, newY + tileSize-2) == "Y")&lt;br /&gt; {&lt;br /&gt;  unit.style.left = newX;&lt;br /&gt;  unit.style.top = newY;&lt;br /&gt;&lt;br /&gt;  if(newX != destX || newY != destY)&lt;br /&gt;  {&lt;br /&gt;   setTimeout("moveUnit(" + unitID + "," + tileDestX +"," + tileDestY+")",5);&lt;br /&gt;  }&lt;br /&gt;  else&lt;br /&gt;  {&lt;br /&gt;   destReached(unitID, destX, destY);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function isWalkable(x,y)&lt;br /&gt;{&lt;br /&gt; var tile = document.getElementById("tile_" + translateTileX(x) + "_" + translateTileY(y))&lt;br /&gt; if(tile.getAttribute("flag") &amp;gt;= 0) return "Y";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; return "N";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function isWalkableTile(x,y)&lt;br /&gt;{&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; if(tile.getAttribute("flag") &amp;gt;= 0) return "Y";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; return "N";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTop(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.top.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getLeft(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.left.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function translateTileX(x)&lt;br /&gt;{&lt;br /&gt; return Math.floor(x/tileSize - originX);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function translateTileY(y)&lt;br /&gt;{&lt;br /&gt; return Math.floor(y/tileSize - originY);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function getTileY(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; return translateTileY(getTop(unit));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTileX(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; return translateTileY(getLeft(unit));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTileY(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; x = Math.floor(getLeft(unit)/tileSize - originX);&lt;br /&gt; y = Math.floor(getTop(unit)/tileSize - originY);&lt;br /&gt;&lt;br /&gt; return y;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Basic HTML page (index.html)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;link type="text/css" href="style.css"rel="stylesheet" /&amp;gt;&lt;br /&gt;&amp;lt;script language=javascript src="map.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script language=javascript&amp;gt;&lt;br /&gt;function tileClicked(x,y)&lt;br /&gt;{&lt;br /&gt;  //called whenever a tile is clicked&lt;br /&gt; moveUnit(1000, x, y);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function destReached(unitID, x, y)&lt;br /&gt;{&lt;br /&gt; //called when ever the unit is done moving to a spot&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function play()&lt;br /&gt;{&lt;br /&gt; //once called, this will loop forever, checking the game state and other things&lt;br /&gt; setTimeout("play()",playSpeed);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function objectsCollided(unit, unitID, enemyID)&lt;br /&gt;{&lt;br /&gt; //called whenever two objects collide&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10); addUnit(1000,4,4);"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="divMap"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="score" style="font-family:verdana;size:14px; background:green;position:absolute;top:5px;left:350px; width:100px height:15px;border:5px solid green;"&amp;gt;&lt;br /&gt; Score: 0&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-6337144287217914756?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/73zquY1xw2F8lhAhCyu9ORYZtzE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/73zquY1xw2F8lhAhCyu9ORYZtzE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/73zquY1xw2F8lhAhCyu9ORYZtzE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/73zquY1xw2F8lhAhCyu9ORYZtzE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/4LPgjU3dX40" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=6337144287217914756" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/6337144287217914756?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/6337144287217914756?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/4LPgjU3dX40/javascript-2d-map-library.html" title="Javascript - 2D Map Library" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/04/javascript-2d-map-library.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMMR3w6fip7ImA9WxFSGUs.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-6771031945507711814</id><published>2010-04-22T12:55:00.000-07:00</published><updated>2010-04-22T13:34:46.216-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-22T13:34:46.216-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="stock" /><category scheme="http://www.blogger.com/atom/ns#" term="ramblings" /><title>Stock Guessing - Programatically</title><content type="html">I've always been interested in stock analytics. Mostly because I have this un-reasonable dream that if I can program a stock "machine" which will trade stocks for me and make me richer than my wildest dreams.&lt;br /&gt;&lt;br /&gt;*Watches as you fall on the floor laughing*&lt;br /&gt;&lt;br /&gt;So now that you are done laughing....I started a blog about a year ago on creating such a program. If your interested &lt;a href="http://mobeamerstock.blogspot.com/"&gt;it's here&lt;/a&gt;. I don't think I'm going to post to it anymore and it..."wonders"...a bit.&lt;br /&gt;&lt;br /&gt;Last night, I fired up the old program I wrote and tinkered with it for a little while. Tormenting myself with that dream I mentioned. To my surprise, I found something interesting...&lt;br /&gt;&lt;br /&gt;The program is setup to run once a day, pick a few stocks and then invest $1,000 into it. It then examines it's buys every day and sells the stock. There is a lot of other stuff going on, but that's the important part.&lt;br /&gt;&lt;br /&gt;If I had $10,000 to invest over the past 60 days and I had done ever trade and sell recommended by the program. I'd have gained $3,679.02. &lt;br /&gt;&lt;br /&gt;I'd have done 33 trades, assuming a $10 commission on each buy and sell, the commissions would cost me $660.&lt;br /&gt;&lt;br /&gt;The program churns through around 3,500 stocks (NYSE and NASDAQ) looking for good trades. It's a lucky day when it finds two picks in a given day.&lt;br /&gt;&lt;br /&gt;For those who are interesting..here are the last 10 or so picks it spit out.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_MXZ6aBwP4Wo/S9Cu1K3MfcI/AAAAAAAAACU/J-x3XmjCeT8/s1600/Trades.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 195px; height: 376px;" src="http://3.bp.blogspot.com/_MXZ6aBwP4Wo/S9Cu1K3MfcI/AAAAAAAAACU/J-x3XmjCeT8/s400/Trades.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5463058576472571330" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm at a loss on how to further test the program to ensure this is not some coincidence. Any suggestions?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-6771031945507711814?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Myi0UyhMxDRzpP08r6KUlEC20-I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Myi0UyhMxDRzpP08r6KUlEC20-I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Myi0UyhMxDRzpP08r6KUlEC20-I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Myi0UyhMxDRzpP08r6KUlEC20-I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/dGe6mmXE-8c" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=6771031945507711814" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/6771031945507711814?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/6771031945507711814?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/dGe6mmXE-8c/stock-guessing-programatically.html" title="Stock Guessing - Programatically" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_MXZ6aBwP4Wo/S9Cu1K3MfcI/AAAAAAAAACU/J-x3XmjCeT8/s72-c/Trades.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/04/stock-guessing-programatically.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0INQ34_eSp7ImA9WxFSF0U.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-7790032951775548438</id><published>2010-04-05T10:43:00.000-07:00</published><updated>2010-04-20T11:53:12.041-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-20T11:53:12.041-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Code: Simple 2D Javascript Map - Part 6</title><content type="html">This code will create a map grid, when you click the grid the green box will move to the tile you clicked. Red boxes will "fall" from the top down at random intervals. If the green box hits a red box, the red box disappears and starts to fall again. Think of it as a catching game.&lt;br /&gt;&lt;br /&gt;This was built to demonstrate one form of collision detection.In my mind there are two ways you can do collision detection. The first method is what most systems and algorithms perform:&lt;br /&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;Calculate the new position of the unit&lt;/li&gt;&lt;li&gt;Cycle through all other units to see if one of them occupies the new position&lt;/li&gt;&lt;li&gt;If no one is occupying then move the unit&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;The second method is to make tiles as walkable as a unit steps on the tile. Then rather then cycling through all the units, you just check the tile the unit is moving to.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;   &lt;ul&gt;&lt;li&gt;Calculate the new position of the unit&lt;/li&gt;&lt;li&gt;Check to see if that tile is occupied&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If no one is occupying then move the unit&lt;br /&gt;  &lt;/li&gt;&lt;/ul&gt; &lt;/blockquote&gt;&lt;br /&gt;The second method means that it "cost" more to move a unit. However it cost less than cycling through all units, every time there is any movement on the screen.&lt;br /&gt;&lt;br /&gt;How did I implement? First, I had to edit the buildMap() function so that each tile has a flag for who is standing on it. So I added the following line inside my buildMap() loops:&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;      d.setAttribute("flag","0");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I then needed a function to set and unset this flag. If you un comment out a few lines, it will change the background of the tile, so that you can see which tiles get marked as unwalkable.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function setWalkableFlag(x, y, flag)&lt;br /&gt;{&lt;br /&gt; var tmpTile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; tmpTile.setAttribute("flag", flag);&lt;br /&gt;&lt;br /&gt; /*&lt;br /&gt; if(flag &gt; 0)&lt;br /&gt; {&lt;br /&gt;  tmpTile.style.background = "yellow";&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  tmpTile.style.background = "#BBB";&lt;br /&gt; }&lt;br /&gt; */&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I also need the unit to "remember" what tile they are on (currTile) and what tile they &lt;b&gt;were&lt;/b&gt; on (priorTile). To do this, I add the following code to the addUnit() function:&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt; d.setAttribute("currTileX",x);&lt;br /&gt; d.setAttribute("currTileY",y);&lt;br /&gt; d.setAttribute("priorTileX",x);&lt;br /&gt; d.setAttribute("priorTileY",y);&lt;br /&gt;      setWalkableFlag(x, y, unitID);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Again, I needed a few "wrapper" functions. One translates a pixel point X to a tile X. To keep things clean I changed the getTile function to use the new translate function. Again, there is plenty of room to optimize.&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function translateTileX(x)&lt;br /&gt;{&lt;br /&gt; return Math.floor(x/tileSize - originX);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function translateTileY(y)&lt;br /&gt;{&lt;br /&gt; return Math.floor(y/tileSize - originY);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function getTileY(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; return translateTileY(getTop(unit));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTileX(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; return translateTileY(getLeft(unit));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we get to the meat and potatoes of coding. The move unit function is where all the collision detection takes place. Reading through the logic of this function reads as follows:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Grab the unit object and the destination tile object&lt;/li&gt;&lt;li&gt;If the destination tile does not exist, stop&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Move 1 pixel closer to the destination&lt;/li&gt;&lt;li&gt;Get the tile located at the &lt;font style="font-weight: bold;"&gt;center &lt;/font&gt;of the &lt;font style="font-weight: bold;"&gt;new &lt;/font&gt;position. (Center of the unit)&lt;/li&gt;&lt;li&gt;If that tile is not flagged or if it is flagged as &lt;font style="font-weight: bold;"&gt;this &lt;/font&gt;unit&lt;/li&gt;&lt;li&gt;Move the unit to the new location&lt;/li&gt;&lt;li&gt;Set the priorTile and currentTile values&lt;/li&gt;&lt;li&gt;Flag the new current tile as walkable&lt;/li&gt;&lt;li&gt;Flag the old prior tile as unwalkable&lt;/li&gt;&lt;li&gt;If we still have not found our destination, repeat in 5 milliseconds&lt;/li&gt;&lt;li&gt;If there is a collision (back at #5), call the collide function&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function moveUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; unit.setAttribute("priorTileX",getTileX(unitID));&lt;br /&gt; unit.setAttribute("priorTileY",getTileY(unitID));&lt;br /&gt;&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; x = getLeft(unit);&lt;br /&gt; y = getTop(unit);&lt;br /&gt; destX = getLeft(tile);&lt;br /&gt; destY = getTop(tile);&lt;br /&gt; newX = x;&lt;br /&gt; newY = y;&lt;br /&gt;&lt;br /&gt; if(x &gt; destX) newX--;&lt;br /&gt; if(x &lt; destX) newX++;  if(y &gt; destY) newY--;&lt;br /&gt; if(y &lt; destY) newY++;   checkX = newX + tileSize/2;  checkY = newY + tileSize/2;   var newTile = document.getElementById("tile_" + translateTileX(checkX) + "_" + translateTileY(checkY))  if(newTile.getAttribute("flag") == "0" || newTile.getAttribute("flag") == unitID)  {   unit.style.left = newX;   unit.style.top = newY;    unit.setAttribute("currTileX",getTileX(unitID));   unit.setAttribute("currTileY",getTileY(unitID));    if(unit.getAttribute("priorTileY") != unit.getAttribute("currTileY") || unit.getAttribute("priorTileX") != unit.getAttribute("currTileX") )   {    //    //mark the current tile as UNwalkable    //    setWalkableFlag(unit.getAttribute("currTileX"), unit.getAttribute("currTileY"), unitID);     //    //mark the old tile as WALKABLE    //    setWalkableFlag(unit.getAttribute("priorTileX"), unit.getAttribute("priorTileY"), "0");   }    if(newX != destX || newY != destY)   {    setTimeout("moveUnit(" + unitID + "," + tileDestX +"," + tileDestY+")",5);   }  }  else  {   //   //we collided   //snap back to last tile   //   objectsCollided(unit, unitID, newTile.getAttribute("flag"));    }    } &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In our game, if the user/player manages to collide with an enemy we will pop the enemy back up to the top for them to start over.&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&lt;br /&gt;function objectsCollided(unit, unitID, enemyID)&lt;br /&gt;{&lt;br /&gt; var tmpTile = document.getElementById("tile_" + unit.getAttribute("priorTileX") + "_" + unit.getAttribute("priorTileY"))&lt;br /&gt; unit.style.top = getTop(tmpTile);&lt;br /&gt; unit.style.left = getLeft(tmpTile);&lt;br /&gt;&lt;br /&gt; if(unitID == 1000)&lt;br /&gt; {&lt;br /&gt;  x = Math.floor(Math.random()*9);&lt;br /&gt;  y = 0;&lt;br /&gt;  jumpUnit(enemyID, x, y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; if(enemyID == 1000)&lt;br /&gt; {&lt;br /&gt;  x = Math.floor(Math.random()*9);&lt;br /&gt;  y = 0;&lt;br /&gt;  jumpUnit(unitID, x, y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One last change, I had to make was in the jumpUnit() function. I found that I needed to flag and unflag the tiles as the unit jumped.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function jumpUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; unit.style.left = getLeft(tile);&lt;br /&gt; unit.style.top = getTop(tile);&lt;br /&gt; //&lt;br /&gt; //mark the current tile as UNwalkable&lt;br /&gt; //&lt;br /&gt; setWalkableFlag(unit.getAttribute("currTileX"), unit.getAttribute("currTileY"), "0");&lt;br /&gt;&lt;br /&gt; //&lt;br /&gt; //mark the old tile as WALKABLE&lt;br /&gt; //&lt;br /&gt; setWalkableFlag(unit.getAttribute("priorTileX"), unit.getAttribute("priorTileY"), "0");&lt;br /&gt;&lt;br /&gt; unit.setAttribute("currTileX",x);&lt;br /&gt; unit.setAttribute("currTileY",y);&lt;br /&gt; unit.setAttribute("priorTileX",x);&lt;br /&gt; unit.setAttribute("priorTileY",y);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that's the entire change I made...the following is the entire code set:&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.tile {&lt;br /&gt;background:#BBB;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.unit {&lt;br /&gt;background:green;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.enemy {&lt;br /&gt;background:red;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script language=javascript&amp;gt;&lt;br /&gt;&lt;br /&gt;var originX = 0;&lt;br /&gt;var originY = 0;&lt;br /&gt;var tileSize = 32;&lt;br /&gt;var mapHeight = 0;&lt;br /&gt;var mapWidth =0;&lt;br /&gt;function buildMap(width, height)&lt;br /&gt;{&lt;br /&gt;mapHeight = height;&lt;br /&gt;mapWidth = width;&lt;br /&gt;&lt;br /&gt;for(x=0;x&amp;lt;width;x++)&lt;br /&gt; for(y=0;y&amp;lt;height;y++)&lt;br /&gt; {&lt;br /&gt;  var d = document.createElement("DIV");&lt;br /&gt;  d.className="tile";&lt;br /&gt;  d.setAttribute("ID","tile_" + x + "_" + y);&lt;br /&gt;  d.style.top = originY + (y*tileSize);&lt;br /&gt;  d.style.left = originX + (x*tileSize);&lt;br /&gt;  d.style.width = tileSize;&lt;br /&gt;  d.style.height = tileSize;&lt;br /&gt;  d.setAttribute("flag","0");&lt;br /&gt;  d.setAttribute("onclick","tileClicked(" + x + "," + y + ")")&lt;br /&gt;  document.getElementById("divMap").appendChild(d);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function tileClicked(x,y)&lt;br /&gt;{&lt;br /&gt; //var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; //tile.style.background = "yellow"&lt;br /&gt;&lt;br /&gt; moveUnit(1000, x, y);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function addUnit(unitID, x,y)&lt;br /&gt;{&lt;br /&gt; var d = document.createElement("DIV");&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; if(unitID == 1000)&lt;br /&gt; {&lt;br /&gt;  d.className="unit";&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  d.className="enemy";&lt;br /&gt; }&lt;br /&gt; d.setAttribute("xVel", 0);&lt;br /&gt; d.setAttribute("yVel", 0);&lt;br /&gt; d.setAttribute("ID","unit_" + unitID);&lt;br /&gt; d.style.top = tile.style.top;&lt;br /&gt; d.style.left = tile.style.left;&lt;br /&gt; d.style.width = tileSize;&lt;br /&gt; d.style.height = tileSize;&lt;br /&gt; d.setAttribute("currTileX",x);&lt;br /&gt; d.setAttribute("currTileY",y);&lt;br /&gt; d.setAttribute("priorTileX",x);&lt;br /&gt; d.setAttribute("priorTileY",y);&lt;br /&gt;&lt;br /&gt; setWalkableFlag(x, y, unitID);&lt;br /&gt;&lt;br /&gt; document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function setWalkableFlag(x, y, flag)&lt;br /&gt;{&lt;br /&gt; var tmpTile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; tmpTile.setAttribute("flag", flag);&lt;br /&gt;&lt;br /&gt; /*&lt;br /&gt; if(flag &amp;gt; 0)&lt;br /&gt; {&lt;br /&gt;  tmpTile.style.background = "yellow";&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  tmpTile.style.background = "#BBB";&lt;br /&gt; }&lt;br /&gt; */&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function jumpUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; unit.style.left = getLeft(tile);&lt;br /&gt; unit.style.top = getTop(tile);&lt;br /&gt; //&lt;br /&gt; //mark the current tile as UNwalkable&lt;br /&gt; //&lt;br /&gt; setWalkableFlag(unit.getAttribute("currTileX"), unit.getAttribute("currTileY"), "0");&lt;br /&gt;&lt;br /&gt; //&lt;br /&gt; //mark the old tile as WALKABLE&lt;br /&gt; //&lt;br /&gt; setWalkableFlag(unit.getAttribute("priorTileX"), unit.getAttribute("priorTileY"), "0");&lt;br /&gt;&lt;br /&gt; unit.setAttribute("currTileX",x);&lt;br /&gt; unit.setAttribute("currTileY",y);&lt;br /&gt; unit.setAttribute("priorTileX",x);&lt;br /&gt; unit.setAttribute("priorTileY",y);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function moveUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; unit.setAttribute("priorTileX",getTileX(unitID));&lt;br /&gt; unit.setAttribute("priorTileY",getTileY(unitID));&lt;br /&gt;&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; x = getLeft(unit);&lt;br /&gt; y = getTop(unit);&lt;br /&gt; destX = getLeft(tile);&lt;br /&gt; destY = getTop(tile);&lt;br /&gt; newX = x;&lt;br /&gt; newY = y;&lt;br /&gt;&lt;br /&gt; if(x &amp;gt; destX) newX--;&lt;br /&gt; if(x &amp;lt; destX) newX++;&lt;br /&gt; if(y &amp;gt; destY) newY--;&lt;br /&gt; if(y &amp;lt; destY) newY++;&lt;br /&gt;&lt;br /&gt; //if(newX &amp;lt; 0)    newX = 0;&lt;br /&gt; //if(newX &amp;gt; mapWidth-1)  newX = mapWidth-1;&lt;br /&gt; //if(newY &amp;lt; 0)    newY = 0;&lt;br /&gt; //if(newY &amp;gt; mapHeight-1)  newY = mapHeight-1;&lt;br /&gt;&lt;br /&gt; checkX = newX + tileSize/2;&lt;br /&gt; checkY = newY + tileSize/2;&lt;br /&gt;&lt;br /&gt; var newTile = document.getElementById("tile_" + translateTileX(checkX) + "_" + translateTileY(checkY))&lt;br /&gt; if(newTile.getAttribute("flag") == "0" || newTile.getAttribute("flag") == unitID)&lt;br /&gt; {&lt;br /&gt;  unit.style.left = newX;&lt;br /&gt;  unit.style.top = newY;&lt;br /&gt;&lt;br /&gt;  unit.setAttribute("currTileX",getTileX(unitID));&lt;br /&gt;  unit.setAttribute("currTileY",getTileY(unitID));&lt;br /&gt;&lt;br /&gt;  if(unit.getAttribute("priorTileY") != unit.getAttribute("currTileY") || unit.getAttribute("priorTileX") != unit.getAttribute("currTileX") )&lt;br /&gt;  {&lt;br /&gt;   //&lt;br /&gt;   //mark the current tile as UNwalkable&lt;br /&gt;   //&lt;br /&gt;   setWalkableFlag(unit.getAttribute("currTileX"), unit.getAttribute("currTileY"), unitID);&lt;br /&gt;&lt;br /&gt;   //&lt;br /&gt;   //mark the old tile as WALKABLE&lt;br /&gt;   //&lt;br /&gt;   setWalkableFlag(unit.getAttribute("priorTileX"), unit.getAttribute("priorTileY"), "0");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if(newX != destX || newY != destY)&lt;br /&gt;  {&lt;br /&gt;   setTimeout("moveUnit(" + unitID + "," + tileDestX +"," + tileDestY+")",5);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  //&lt;br /&gt;  //we collided&lt;br /&gt;  //snap back to last tile&lt;br /&gt;  //&lt;br /&gt;  objectsCollided(unit, unitID, newTile.getAttribute("flag"));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function objectsCollided(unit, unitID, enemyID)&lt;br /&gt;{&lt;br /&gt; var tmpTile = document.getElementById("tile_" + unit.getAttribute("priorTileX") + "_" + unit.getAttribute("priorTileY"))&lt;br /&gt; unit.style.top = getTop(tmpTile);&lt;br /&gt; unit.style.left = getLeft(tmpTile);&lt;br /&gt;&lt;br /&gt; if(unitID == 1000)&lt;br /&gt; {&lt;br /&gt;  x = Math.floor(Math.random()*9);&lt;br /&gt;  y = 0;&lt;br /&gt;  jumpUnit(enemyID, x, y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; if(enemyID == 1000)&lt;br /&gt; {&lt;br /&gt;  x = Math.floor(Math.random()*9);&lt;br /&gt;  y = 0;&lt;br /&gt;  jumpUnit(unitID, x, y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function getTop(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.top.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getLeft(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.left.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function translateTileX(x)&lt;br /&gt;{&lt;br /&gt; return Math.floor(x/tileSize - originX);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function translateTileY(y)&lt;br /&gt;{&lt;br /&gt; return Math.floor(y/tileSize - originY);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function getTileY(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; return translateTileY(getTop(unit));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTileX(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; return translateTileY(getLeft(unit));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTileY(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; x = Math.floor(getLeft(unit)/tileSize - originX);&lt;br /&gt; y = Math.floor(getTop(unit)/tileSize - originY);&lt;br /&gt;&lt;br /&gt; return y;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var playSpeed = 1000;&lt;br /&gt;var numUnits = 0;&lt;br /&gt;var maxNumUnits = 5;&lt;br /&gt;function play()&lt;br /&gt;{&lt;br /&gt; if(numUnits &amp;lt; maxNumUnits)&lt;br /&gt; {&lt;br /&gt;  unitID = 1001+numUnits&lt;br /&gt;  x = Math.floor(Math.random()*9);&lt;br /&gt;  speed = Math.floor(Math.random()*3);&lt;br /&gt;  addUnit(unitID,x,0);&lt;br /&gt;  var unit = document.getElementById("unit_" + unitID);&lt;br /&gt;  unit.setAttribute("xVel", 0);&lt;br /&gt;  unit.setAttribute("yVel", speed+1);&lt;br /&gt;  numUnits++;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; for(i=0;i&amp;lt;numUnits;i++)&lt;br /&gt; {&lt;br /&gt;  unitID = 1001+i;&lt;br /&gt;  var unit = document.getElementById("unit_" + unitID);&lt;br /&gt;  x = getTileX(unitID) + parseInt(unit.getAttribute("xVel"));&lt;br /&gt;  y = getTileY(unitID) + parseInt(unit.getAttribute("yVel"));&lt;br /&gt;&lt;br /&gt;  if(y &amp;gt;= mapHeight)&lt;br /&gt;  {&lt;br /&gt;   x = Math.floor(Math.random()*9);&lt;br /&gt;   y=0;&lt;br /&gt;   jumpUnit(unitID, x, y);&lt;br /&gt;  }&lt;br /&gt;  moveUnit(1001+i, x,y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; setTimeout("play()",playSpeed);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10); addUnit(1000,4,4);play();"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="divMap"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Question: How would you go about adding a score indicator?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-7790032951775548438?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/G7N7fmChe6uG67nGDvP5MI9tqP4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G7N7fmChe6uG67nGDvP5MI9tqP4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/G7N7fmChe6uG67nGDvP5MI9tqP4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G7N7fmChe6uG67nGDvP5MI9tqP4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/1D9QlziSUzU" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=7790032951775548438" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/7790032951775548438?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/7790032951775548438?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/1D9QlziSUzU/code-simple-2d-javascript-map-part-6.html" title="Code: Simple 2D Javascript Map - Part 6" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-6.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEDQHk_fCp7ImA9WxFSE04.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-3951623586094572674</id><published>2010-04-05T07:58:00.000-07:00</published><updated>2010-04-15T06:37:51.744-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-15T06:37:51.744-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Code: Simple 2D Javascript Map - Part 5</title><content type="html">This code will show how to create enemies and move them around the screen. It's going to randomly create 5 red boxes which will "fall" from the top of the grid to the bottom. The user can click a tile and the green box will move to the tile clicked. There is no collision detection...yet. I'm keeping this as simple as possible so in this example, "enemies" will drop from the top of the screen. Your job is to dodge them.&lt;br /&gt;&lt;br /&gt;The play function will get called every one second (playSpeed). It will add a new enemy until it has added 5 enemies. It chooses a random location at the top of the map, places the unit there.&lt;br /&gt;&lt;br /&gt;It will then pick a random speed and set the y velocity (think downward speed) equal to this random speed value.&lt;br /&gt;&lt;br /&gt;The second piece has the magic. It cycles through all enemy units and sets their next location to 3 spaces below where the unit currently is. Notice that this where our new functions get called.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;var playSpeed = 1000;&lt;br /&gt;var numUnits = 0;&lt;br /&gt;var maxNumUnits = 5;&lt;br /&gt;function play()&lt;br /&gt;{&lt;br /&gt; if(numUnits &lt; unitid =" 1001+numUnits" x =" Math.floor(Math.random()*9);" speed =" Math.floor(Math.random()*3);" unit =" document.getElementById(" i="0;i&lt;numunits;i++)" unitid="1001+i;" var="" unit="document.getElementById(&amp;quot;unit_&amp;quot;" x="getTileX(unitID)" xvel="" yvel="" y="getTileY(unitID)"&gt;= mapHeight)&lt;br /&gt;  {&lt;br /&gt;   x = Math.floor(Math.random()*9);&lt;br /&gt;   y=0;&lt;br /&gt;   jumpUnit(unitID, x, y);&lt;br /&gt;  }&lt;br /&gt;  moveUnit(1001+i, x,y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; setTimeout("play()",playSpeed);&lt;br /&gt;}&lt;br /&gt;&lt;/numunits;i++)&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Other changes&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Again, we have some plain Jane functions to get the tile location (x and y) of where our units is located. Make a note to yourself, there is plenty of room to optimize this code. It's dog slow.&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function getTileX(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; x = getLeft(unit)/tileSize - originX;&lt;br /&gt; y = getTop(unit)/tileSize - originY;&lt;br /&gt;&lt;br /&gt; return x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTileY(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; x = getLeft(unit)/tileSize - originX;&lt;br /&gt; y = getTop(unit)/tileSize - originY;&lt;br /&gt;&lt;br /&gt; return y;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We also need to create a style for our enemy units. So I added this to the style.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;.enemy {&lt;br /&gt;background:red;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Since we are moving random objects around, we need to start tracking the map height and width. So I changed the build map function.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;var mapHeight = 0;&lt;br /&gt;var mapWidth =0;&lt;br /&gt;function buildMap(width, height)&lt;br /&gt;{&lt;br /&gt;mapHeight = height;&lt;br /&gt;mapWidth = width;&lt;br /&gt;&lt;br /&gt;for(x=0;x&amp;lt;width;x++) y=0;y&amp;lt;height;y++);x++)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Again, because we are moving enemies around randomly, need a bit of error catching added to the move function. If we try to move to a tile that does not exist, just stop moving.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function moveUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; x = getLeft(unit);&lt;br /&gt; y = getTop(unit);&lt;br /&gt; destX = getLeft(tile)&lt;br /&gt;      ......&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally, I needed a function which will take an existing unit and "jump" them to a specific place on the map. This means they don't "move" one pixel at a time, but instead are immediately placed at that location:&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function jumpUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; unit.style.left = getLeft(tile);&lt;br /&gt; unit.style.top = getTop(tile);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Last but not least, we have to call our new play function from within the body tag.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10); addUnit(1000,4,4); play()"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finally, the entire page looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.tile {&lt;br /&gt;background:#BBB;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.unit {&lt;br /&gt;background:green;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.enemy {&lt;br /&gt;background:red;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script language=javascript&amp;gt;&lt;br /&gt;&lt;br /&gt;var originX = 0;&lt;br /&gt;var originY = 0;&lt;br /&gt;var tileSize = 32;&lt;br /&gt;var mapHeight = 0;&lt;br /&gt;var mapWidth =0;&lt;br /&gt;function buildMap(width, height)&lt;br /&gt;{&lt;br /&gt;mapHeight = height;&lt;br /&gt;mapWidth = width;&lt;br /&gt;&lt;br /&gt;for(x=0;x&amp;lt;width;x++)&lt;br /&gt;for(y=0;y&amp;lt;height;y++)&lt;br /&gt;{&lt;br /&gt; var d = document.createElement("DIV");&lt;br /&gt; d.className="tile";&lt;br /&gt; d.setAttribute("ID","tile_" + x + "_" + y);&lt;br /&gt; d.style.top = originY + (y*tileSize);&lt;br /&gt; d.style.left = originX + (x*tileSize);&lt;br /&gt; d.style.width = tileSize;&lt;br /&gt; d.style.height = tileSize;&lt;br /&gt; d.setAttribute("onclick","tileClicked(" + x + "," + y + ")")&lt;br /&gt; document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function tileClicked(x,y)&lt;br /&gt;{&lt;br /&gt; //var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; //tile.style.background = "yellow"&lt;br /&gt;&lt;br /&gt; moveUnit(1000, x, y);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function addUnit(unitID, x,y)&lt;br /&gt;{&lt;br /&gt; var d = document.createElement("DIV");&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; if(unitID == 1000)&lt;br /&gt; {&lt;br /&gt;  d.className="unit";&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  d.className="enemy";&lt;br /&gt; }&lt;br /&gt; d.setAttribute("xVel", 0);&lt;br /&gt; d.setAttribute("yVel", 0);&lt;br /&gt; d.setAttribute("ID","unit_" + unitID);&lt;br /&gt; d.style.top = tile.style.top;&lt;br /&gt; d.style.left = tile.style.left;&lt;br /&gt; d.style.width = tileSize;&lt;br /&gt; d.style.height = tileSize;&lt;br /&gt; document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function jumpUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; unit.style.left = getLeft(tile);&lt;br /&gt; unit.style.top = getTop(tile);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function moveUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; if(!tile)&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt; x = getLeft(unit);&lt;br /&gt; y = getTop(unit);&lt;br /&gt; destX = getLeft(tile);&lt;br /&gt; destY = getTop(tile);&lt;br /&gt; newX = x;&lt;br /&gt; newY = y;&lt;br /&gt;&lt;br /&gt; if(x &amp;gt; destX) newX--;&lt;br /&gt; if(x &amp;lt; destX) newX++;&lt;br /&gt; if(y &amp;gt; destY) newY--;&lt;br /&gt; if(y &amp;lt; destY) newY++;&lt;br /&gt;&lt;br /&gt; unit.style.left = newX;&lt;br /&gt; unit.style.top = newY;&lt;br /&gt;&lt;br /&gt; if(newX != destX || newY != destY)&lt;br /&gt; {&lt;br /&gt;  setTimeout("moveUnit(" + unitID + "," + tileDestX +"," + tileDestY+")",5);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function getTop(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.top.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getLeft(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.left.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTileX(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; x = getLeft(unit)/tileSize - originX;&lt;br /&gt; y = getTop(unit)/tileSize - originY;&lt;br /&gt;&lt;br /&gt; return x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getTileY(unitID)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; x = getLeft(unit)/tileSize - originX;&lt;br /&gt; y = getTop(unit)/tileSize - originY;&lt;br /&gt;&lt;br /&gt; return y;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var playSpeed = 1000;&lt;br /&gt;var numUnits = 0;&lt;br /&gt;var maxNumUnits = 5;&lt;br /&gt;function play()&lt;br /&gt;{&lt;br /&gt; if(numUnits &amp;lt; maxNumUnits)&lt;br /&gt; {&lt;br /&gt;  unitID = 1001+numUnits&lt;br /&gt;  x = Math.floor(Math.random()*9);&lt;br /&gt;  speed = Math.floor(Math.random()*3);&lt;br /&gt;  addUnit(unitID,x,0);&lt;br /&gt;  var unit = document.getElementById("unit_" + unitID);&lt;br /&gt;  unit.setAttribute("xVel", 0);&lt;br /&gt;  unit.setAttribute("yVel", speed+1);&lt;br /&gt;  numUnits++;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; for(i=0;i&amp;lt;numUnits;i++)&lt;br /&gt; {&lt;br /&gt;  unitID = 1001+i;&lt;br /&gt;  var unit = document.getElementById("unit_" + unitID);&lt;br /&gt;  x = getTileX(unitID) + parseInt(unit.getAttribute("xVel"));&lt;br /&gt;  y = getTileY(unitID) + parseInt(unit.getAttribute("yVel"));&lt;br /&gt;&lt;br /&gt;  if(y &amp;gt;= mapHeight)&lt;br /&gt;  {&lt;br /&gt;   x = Math.floor(Math.random()*9);&lt;br /&gt;   y=0;&lt;br /&gt;   jumpUnit(unitID, x, y);&lt;br /&gt;  }&lt;br /&gt;  moveUnit(1001+i, x,y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; setTimeout("play()",playSpeed);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10); addUnit(1000,4,4); play()"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="divMap"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-3951623586094572674?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/azYdJ9mDKV22owXfrBW_5LWph_M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/azYdJ9mDKV22owXfrBW_5LWph_M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/azYdJ9mDKV22owXfrBW_5LWph_M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/azYdJ9mDKV22owXfrBW_5LWph_M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/xDWVAcggoy0" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=3951623586094572674" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/3951623586094572674?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/3951623586094572674?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/xDWVAcggoy0/code-simple-2d-javascript-map-part-5.html" title="Code: Simple 2D Javascript Map - Part 5" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-5.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04HRn04cCp7ImA9WxFSEk0.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-290532868375175975</id><published>2010-04-02T07:44:00.000-07:00</published><updated>2010-04-13T17:45:37.338-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-13T17:45:37.338-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Code: Simple 2D Javascript Map - Part 4</title><content type="html">What's that you say, you want to move the character around the screen.&lt;br /&gt;&lt;br /&gt;OK, ok, ok...here we go.&lt;br /&gt;&lt;br /&gt;Because we will need to get the exact position of the div objects, I use the following two functions (In all fairness there are better, faster, more accurate ways to get the position of a div tag, but this has worked for me and is simple enough for my simple mind to grasp.)&lt;br /&gt;&lt;br /&gt;You pass them an object and they give you back the position of the object.&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function getTop(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.top.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getLeft(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.left.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A bit boring, nothing to fascinating in those functions. However here is where things get a bit more exciting. The following function will move any unit object to the desired &lt;b&gt;Tile&lt;/b&gt; position.&lt;br /&gt;&lt;br /&gt;We pass in the unitID we want to move, and the &lt;b&gt;TILE&lt;/b&gt; x and y we want to move to. The function will:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Get the unit's and the tile's position&lt;/li&gt;&lt;li&gt;Compare the two positions and move the unit closer to the tile &lt;b&gt;by one pixel&lt;/b&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;At the very end of the function, if we have not reached our destination, we call the same function in 5 milliseconds.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function moveUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; x = getLeft(unit);&lt;br /&gt; y = getTop(unit);&lt;br /&gt; destX = getLeft(tile);&lt;br /&gt; destY = getTop(tile);&lt;br /&gt; newX = x;&lt;br /&gt; newY = y;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; if(x &gt; destX) newX--;&lt;br /&gt; if(x &lt;&gt; destY) newY--;&lt;br /&gt; if(y &lt; left =" newX;" top =" newY;"&gt;&lt;br /&gt;&lt;br /&gt;Now that moves the unit around, but no one is actually calling this function so&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Full Code:&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.tile {&lt;br /&gt;background:#BBB;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.unit {&lt;br /&gt;background:green;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script language=javascript&amp;gt;&lt;br /&gt;&lt;br /&gt;var originX = 0;&lt;br /&gt;var originY = 0;&lt;br /&gt;var tileSize = 32;&lt;br /&gt;&lt;br /&gt;function buildMap(width, height)&lt;br /&gt;{&lt;br /&gt;for(x=0;x&amp;lt;width;x++)&lt;br /&gt;for(y=0;y&amp;lt;height;y++)&lt;br /&gt;{&lt;br /&gt;var d = document.createElement("DIV");&lt;br /&gt;d.className="tile";&lt;br /&gt;d.setAttribute("ID","tile_" + x + "_" + y);&lt;br /&gt;d.style.top = originY + (y*tileSize);&lt;br /&gt;d.style.left = originX + (x*tileSize);&lt;br /&gt;d.style.width = tileSize;&lt;br /&gt;d.style.height = tileSize;&lt;br /&gt;d.setAttribute("onclick","tileClicked(" + x + "," + y + ")")&lt;br /&gt;document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function tileClicked(x,y)&lt;br /&gt;{&lt;br /&gt; //var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; //tile.style.background = "yellow"&lt;br /&gt;&lt;br /&gt; moveUnit(1000, x, y);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function addUnit(unitID, x,y)&lt;br /&gt;{&lt;br /&gt; var d = document.createElement("DIV");&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; d.className="unit";&lt;br /&gt; d.setAttribute("ID","unit_" + unitID);&lt;br /&gt; d.style.top = tile.style.top;&lt;br /&gt; d.style.left = tile.style.left;&lt;br /&gt; d.style.width = tileSize;&lt;br /&gt; d.style.height = tileSize;&lt;br /&gt; document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function moveUnit(unitID, tileDestX, tileDestY)&lt;br /&gt;{&lt;br /&gt; var unit = document.getElementById("unit_" + unitID);&lt;br /&gt; var tile = document.getElementById("tile_" + tileDestX + "_" + tileDestY)&lt;br /&gt; x = getLeft(unit);&lt;br /&gt; y = getTop(unit);&lt;br /&gt; destX = getLeft(tile);&lt;br /&gt; destY = getTop(tile);&lt;br /&gt; newX = x;&lt;br /&gt; newY = y;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; if(x &amp;gt; destX) newX--;&lt;br /&gt; if(x &amp;lt; destX) newX++;&lt;br /&gt; if(y &amp;gt; destY) newY--;&lt;br /&gt; if(y &amp;lt; destY) newY++;&lt;br /&gt;&lt;br /&gt; unit.style.left = newX;&lt;br /&gt; unit.style.top = newY;&lt;br /&gt;&lt;br /&gt; if(newX != destX || newY != destY)&lt;br /&gt; {&lt;br /&gt;  setTimeout("moveUnit(" + unitID + "," + tileDestX +"," + tileDestY+")",5);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function getTop(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.top.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getLeft(obj)&lt;br /&gt;{&lt;br /&gt; if(obj)&lt;br /&gt; {&lt;br /&gt;  return parseInt(obj.style.left.replace("px",""));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10); addUnit(1000,4,4)"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="divMap"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For giggles, I used this quick function to test play it. The function adds a number of units and randomly moves them around the screen. My desktop (Intel 2 Duo 2.2GH with 2GB Ram) can handle about 20 units in firefox, before it gets a bit odd.&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;var playSpeed = 3000;&lt;br /&gt;var numUnits = 0;&lt;br /&gt;var maxNumUnits = 5;&lt;br /&gt;function play()&lt;br /&gt;{&lt;br /&gt; while(numUnits &lt; i="0;i&lt;numunits;i++)" y="Math.floor(Math.random()*9);" x="Math.floor(Math.random()*9);"&gt;&lt;/numunits;i++)&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-290532868375175975?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/qMQZCmw1Bu66WbFahvCRXCeD5tc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qMQZCmw1Bu66WbFahvCRXCeD5tc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/qMQZCmw1Bu66WbFahvCRXCeD5tc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qMQZCmw1Bu66WbFahvCRXCeD5tc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/_QfcfmFqRpo" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=290532868375175975" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/290532868375175975?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/290532868375175975?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/_QfcfmFqRpo/code-simple-2d-javascript-map-part-4.html" title="Code: Simple 2D Javascript Map - Part 4" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-4.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMHSXo4cCp7ImA9WxFSEEo.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-5493149442277640921</id><published>2010-04-02T07:36:00.001-07:00</published><updated>2010-04-12T06:20:38.438-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-12T06:20:38.438-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Code: Simple 2D Javascript Map - Part 3</title><content type="html">All right, let's put a character on the board!&lt;br /&gt;&lt;br /&gt;It's not difficult, first we create a function that will add the character for us. So we know that we will need to know the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A distinct ID for the unit (unitID)&lt;/li&gt;&lt;li&gt;The x and y of where to place the unit.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Things to note:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We have to get the tile at X, Y.&lt;/li&gt;&lt;li&gt;We set the new div's tile to the Top and Left of the tile&lt;/li&gt;&lt;li&gt;We give the div tag a distinct "ID"&lt;/li&gt;&lt;li&gt;We give the new div tag a class of "unit"&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function addUnit(unitID, x,y)&lt;br /&gt;{&lt;br /&gt; var d = document.createElement("DIV");&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; d.className="unit";&lt;br /&gt; d.setAttribute("ID","unit_" + unitID);&lt;br /&gt; d.style.top = tile.style.top;&lt;br /&gt; d.style.left = tile.style.left;&lt;br /&gt; d.style.width = tileSize;&lt;br /&gt; d.style.height = tileSize;&lt;br /&gt; document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We've created a new css class "unit" so we need to add the following to our styles:&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;.unit {&lt;br /&gt;background:green;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally, we actually add the unit to the map when the body is loading.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10); addUnit(1000,4,4)"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So the full page, looks like this...&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.tile {&lt;br /&gt;background:#BBB;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.unit {&lt;br /&gt;background:green;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script language=javascript&amp;gt;&lt;br /&gt;&lt;br /&gt;var originX = 0;&lt;br /&gt;var originY = 0;&lt;br /&gt;var tileSize = 32;&lt;br /&gt;&lt;br /&gt;function buildMap(width, height)&lt;br /&gt;{&lt;br /&gt;for(x=0;x&amp;lt;width;x++)&lt;br /&gt; for(y=0;y&amp;lt;height;y++)&lt;br /&gt; {&lt;br /&gt;  var d = document.createElement("DIV");&lt;br /&gt;  d.className="tile";&lt;br /&gt;  d.setAttribute("ID","tile_" + x + "_" + y);&lt;br /&gt;  d.style.top = originY + (y*tileSize);&lt;br /&gt;  d.style.left = originX + (x*tileSize);&lt;br /&gt;  d.style.width = tileSize;&lt;br /&gt;  d.style.height = tileSize;&lt;br /&gt;  d.setAttribute("onclick","tileClicked(" + x + "," + y + ")")&lt;br /&gt;  document.getElementById("divMap").appendChild(d);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function tileClicked(x,y)&lt;br /&gt;{&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; tile.style.background = "yellow"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function addUnit(unitID, x,y)&lt;br /&gt;{&lt;br /&gt; var d = document.createElement("DIV");&lt;br /&gt; var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt; d.className="unit";&lt;br /&gt; d.setAttribute("ID","unit_" + unitID);&lt;br /&gt; d.style.top = tile.style.top;&lt;br /&gt; d.style.left = tile.style.left;&lt;br /&gt; d.style.width = tileSize;&lt;br /&gt; d.style.height = tileSize;&lt;br /&gt; document.getElementById("divMap").appendChild(d);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10); addUnit(1000,4,4)"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="divMap"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-5493149442277640921?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-llPMiTWxOWfk1TBIpl55e9vLBg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-llPMiTWxOWfk1TBIpl55e9vLBg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-llPMiTWxOWfk1TBIpl55e9vLBg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-llPMiTWxOWfk1TBIpl55e9vLBg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/TQBZBecAnC4" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=5493149442277640921" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/5493149442277640921?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/5493149442277640921?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/TQBZBecAnC4/code-simple-2d-javascript-map-part-3.html" title="Code: Simple 2D Javascript Map - Part 3" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQ3c_eyp7ImA9WxFTFEo.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-3526519393346129633</id><published>2010-04-02T07:25:00.000-07:00</published><updated>2010-04-05T07:18:12.943-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-05T07:18:12.943-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Code: Simple 2D Javascript Map - Part 2</title><content type="html">So, we've built a map in javascript and displayed it. Quite impressive...or maybe not.&lt;br /&gt;&lt;br /&gt;Now we want to make something happen when the user clicks on a tile. In this example, we will change the background. First we add a simple function which we will call whenever a tile is clicked.&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;function tileClicked(x,y)&lt;br /&gt;{&lt;br /&gt;   var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt;   tile.style.background = "yellow"&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, we will attach this function to all the tiles, so within our buildMap() function we add this line of code:&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;d.setAttribute("onclick","tileClicked(" + x + "," + y + ")")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's it...now when you click a tile, it turns yellow. Why don't you try to change it so that the background has an image and the image changes as you click it?&lt;br /&gt;&lt;br /&gt;Full Code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.tile {&lt;br /&gt;background:#BBB;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script language=javascript&amp;gt;&lt;br /&gt;&lt;br /&gt;var originX = 0;&lt;br /&gt;var originY = 0;&lt;br /&gt;var tileSize = 32;&lt;br /&gt;&lt;br /&gt;function buildMap(width, height)&lt;br /&gt;{&lt;br /&gt;for(x=0;x&amp;lt;width;x++)&lt;br /&gt; for(y=0;y&amp;lt;height;y++)&lt;br /&gt; {&lt;br /&gt;  var d = document.createElement("DIV");&lt;br /&gt;  d.className="tile";&lt;br /&gt;  d.setAttribute("ID","tile_" + x + "_" + y);&lt;br /&gt;  d.style.top = originY + (y*tileSize);&lt;br /&gt;  d.style.left = originX + (x*tileSize);&lt;br /&gt;  d.style.width = tileSize;&lt;br /&gt;  d.style.height = tileSize;&lt;br /&gt;  d.setAttribute("onclick","tileClicked(" + x + "," + y + ")")&lt;br /&gt;  document.getElementById("divMap").appendChild(d);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function tileClicked(x,y)&lt;br /&gt;{&lt;br /&gt;   var tile = document.getElementById("tile_" + x + "_" + y)&lt;br /&gt;   tile.style.background = "yellow"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10)"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="divMap"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-3526519393346129633?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8M8JtWo73vGpchMpJytMar0Qtqw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8M8JtWo73vGpchMpJytMar0Qtqw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8M8JtWo73vGpchMpJytMar0Qtqw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8M8JtWo73vGpchMpJytMar0Qtqw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/uLi9BGZKQg0" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=3526519393346129633" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/3526519393346129633?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/3526519393346129633?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/uLi9BGZKQg0/code-simple-2d-javascript-map-part-2.html" title="Code: Simple 2D Javascript Map - Part 2" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/04/code-simple-2d-javascript-map-part-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUANSH84eSp7ImA9WxFTEkw.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-140373232334184368</id><published>2010-03-29T12:47:00.000-07:00</published><updated>2010-04-02T07:16:39.131-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-02T07:16:39.131-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Code: Simple 2D Javascript Map</title><content type="html">A friend of mine asked me what is the quickest, simplest way to create a 2d map. Think top down, grid like map.&lt;br /&gt;&lt;br /&gt;Here is 35 lines of javascript code that will do just that. Enjoy...&lt;br /&gt;&lt;br /&gt;&lt;pre class="postCode"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.tile {&lt;br /&gt;background:#BBB;&lt;br /&gt;border:1px solid #999;&lt;br /&gt;position:absolute;&lt;br /&gt;top:0px;left:0px;&lt;br /&gt;width:5px;height:5px;&lt;br /&gt;overflow:hidden&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script language=javascript&amp;gt;&lt;br /&gt;&lt;br /&gt;var originX = 0;&lt;br /&gt;var originY = 0;&lt;br /&gt;var tileSize = 32;&lt;br /&gt;&lt;br /&gt;function buildMap(width, height)&lt;br /&gt;{&lt;br /&gt; for(x=0;x&amp;lt;width;x++)&lt;br /&gt;  for(y=0;y&amp;lt;height;y++)&lt;br /&gt;  {&lt;br /&gt;   var d = document.createElement("DIV");&lt;br /&gt;   d.className="tile";&lt;br /&gt;   d.setAttribute("ID","tile_" + x + "_" + y);&lt;br /&gt;   d.style.top = originY + (y*tileSize);&lt;br /&gt;   d.style.left = originX + (x*tileSize);&lt;br /&gt;   d.style.width = tileSize;&lt;br /&gt;   d.style.height = tileSize;&lt;br /&gt;   document.getElementById("divMap").appendChild(d);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;body onload="buildMap(10,10)"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;div id="divMap"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-140373232334184368?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CNjHQWT6g_mQa2LVHK0cy00Fidg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CNjHQWT6g_mQa2LVHK0cy00Fidg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CNjHQWT6g_mQa2LVHK0cy00Fidg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CNjHQWT6g_mQa2LVHK0cy00Fidg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/6FJWar3Jku4" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=140373232334184368" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/140373232334184368?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/140373232334184368?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/6FJWar3Jku4/code-simple-2d-javascript-map.html" title="Code: Simple 2D Javascript Map" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/03/code-simple-2d-javascript-map.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQNRXg7eSp7ImA9Wx9WGEQ.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-1721439920029645811</id><published>2010-03-19T09:45:00.000-07:00</published><updated>2011-01-24T10:39:54.601-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-24T10:39:54.601-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AI" /><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Artificial Intelligence - Dreaming and Learning</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_MXZ6aBwP4Wo/S6OqQCCdGXI/AAAAAAAAACM/S0uYM75gnx8/s1600-h/Ai+-+8.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 315px;" src="http://3.bp.blogspot.com/_MXZ6aBwP4Wo/S6OqQCCdGXI/AAAAAAAAACM/S0uYM75gnx8/s400/Ai+-+8.PNG" alt="" id="BLOGGER_PHOTO_ID_5450387166450227570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;So last but most importantly, what does the Ai do when its sensors are detecting nothing?&lt;br /&gt;&lt;br /&gt;It has two options.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Use Active/Aggressive sensors&lt;/span&gt;&lt;br /&gt;The first is to turn on some active sensors. We can assume that some sensor it has can “roam” or find new views of it’s environment. Let’s say we have a web parsing sensor, it reads HTML and brings back links. This sensor would not be active unless there is nothing else going on. The Ai could decide to activate it. There could be an array of these type sensors.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Dream&lt;/span&gt;&lt;br /&gt;The second option that it has is to dream. When dreaming the Ai will:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;  Search it’s Long term memory for a random data variable&lt;/li&gt;&lt;li&gt;  Use this data and feed it to a all Evaluators except for “the best”.&lt;/li&gt;&lt;li&gt;  Any evaluator that understood the data gets a chance to process it&lt;/li&gt;&lt;li&gt;  Any evaluator that understood the data would get passed additional data elements that are “similar” to the original”&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Doing this allows the Brain to evaluate if it’s truly has the best evaluator and sensor collaborated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-1721439920029645811?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/G5wJeBnJ9ejiVV8CGzZlktE7UsQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G5wJeBnJ9ejiVV8CGzZlktE7UsQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/G5wJeBnJ9ejiVV8CGzZlktE7UsQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G5wJeBnJ9ejiVV8CGzZlktE7UsQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/o6-bVoq0NUs" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=1721439920029645811" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/1721439920029645811?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/1721439920029645811?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/o6-bVoq0NUs/artificial-intelligence-dreaming-and.html" title="Artificial Intelligence - Dreaming and Learning" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_MXZ6aBwP4Wo/S6OqQCCdGXI/AAAAAAAAACM/S0uYM75gnx8/s72-c/Ai+-+8.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/03/artificial-intelligence-dreaming-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUHSX47cSp7ImA9WxBaFk4.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-4561709522913886879</id><published>2010-03-19T09:43:00.000-07:00</published><updated>2010-03-26T12:53:58.009-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-26T12:53:58.009-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Artificial Intelligence - Memory Management Example</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_MXZ6aBwP4Wo/S6Op29NLkBI/AAAAAAAAACE/b8Nc2Fn2-o0/s1600-h/Ai+-+7.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 356px; height: 400px;" src="http://4.bp.blogspot.com/_MXZ6aBwP4Wo/S6Op29NLkBI/AAAAAAAAACE/b8Nc2Fn2-o0/s400/Ai+-+7.PNG" alt="" id="BLOGGER_PHOTO_ID_5450386735656308754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;So, let’s image that its time to bring the Ai Online. We’ve built all the components and we’re ready to go.&lt;br /&gt;&lt;br /&gt;Here’s how the first 1,000 interactions with if the Ai was only attached to a “Textbox” sensor.&lt;br /&gt;&lt;br /&gt;Definitely take a look at the picture as it conveys a lot more but briefly:&lt;br /&gt;&lt;br /&gt;“Hi” comes through the textbox sensor, the Ai stumbles through Evaluators till it hits the Language one, which say “I understand this data”, the Ai says ok and lets the evaluator do its thing.&lt;br /&gt;&lt;br /&gt;The next time the textbox sensor fires off, the Ai gives it to the only Evaluator it knows Language, language handles things smoothly. This takes place 999 times.&lt;br /&gt;&lt;br /&gt;However on interaction 1,000 along comes a math request “3+9”. The language evaluator says…Ummm, no I can’t do anything with this. Again the Ai stumbles around until it hits the Math evaluator, who says, yeah…I can do something with it.&lt;br /&gt;&lt;br /&gt;Now when textbox fires off, the brain will randomly ask Math…Do you understand this stuff…If Math says yes, the Brain lets it handle the text. If the Math says “no”, brain turns to Language and passes stuff off.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;&lt;br /&gt;This is not the most efficient way and if you notice it never actually pattern matches against what comes in on the textbox sensor.&lt;br /&gt;&lt;br /&gt;However, if a different sensor is setup for math functions this approach would lead to an efficient Ai. Math coming across a speech/text sensor would be like being asked does this spell BLUE. Humans can do it, its just…odd, thus we are more likely to answer incorrectly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-4561709522913886879?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_OCkUvtZTVaHVsILkvLuwmJlEBE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_OCkUvtZTVaHVsILkvLuwmJlEBE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_OCkUvtZTVaHVsILkvLuwmJlEBE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_OCkUvtZTVaHVsILkvLuwmJlEBE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/swj2L2AuoWg" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=4561709522913886879" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/4561709522913886879?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/4561709522913886879?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/swj2L2AuoWg/artificial-intelligence-memory_19.html" title="Artificial Intelligence - Memory Management Example" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_MXZ6aBwP4Wo/S6Op29NLkBI/AAAAAAAAACE/b8Nc2Fn2-o0/s72-c/Ai+-+7.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/03/artificial-intelligence-memory_19.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUGQng9eyp7ImA9WxBaFk4.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-7509780058826791673</id><published>2010-03-19T09:41:00.001-07:00</published><updated>2010-03-26T12:53:43.663-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-26T12:53:43.663-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Artificial Intelligence - Memory Management</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S6OpYBDjkbI/AAAAAAAAAB8/SrrMLHNY16s/s1600-h/Ai+-+6.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S6OpYBDjkbI/AAAAAAAAAB8/SrrMLHNY16s/s400/Ai+-+6.PNG" alt="" id="BLOGGER_PHOTO_ID_5450386204113736114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Let’s talk Memory,&lt;br /&gt;&lt;br /&gt;A Brain is going to have to recall things, store numbers, understand relationships and all sorts of stuff that deal with “recall”. This is where the memory module will come into play.&lt;br /&gt;&lt;br /&gt;Memory will consists of 4 pieces. All parts of the memory are available to the Brain and the Evaluators. Memory is not available to sensors and or motors.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Short Term Memory&lt;/span&gt;&lt;br /&gt;Short term memory is for swift, context based data. It will consist of a Sensor ID, the data, a timestamp, and number of times accessed counter. At first this will be a straight copy of the sensor stack. However it will change over time. The number of items/rows in short term memory will be dictated by the amount of time it takes to search it and retrieve a specific piece of data. For example, if a query against short term memory takes longer than 100 milliseconds, the memory handler will move the 10 least accessed memories to long term memory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Long Term Memory&lt;/span&gt;&lt;br /&gt;Long term memory will look just like short term memory. Sensor ID, data and timestamp for when it came in. However Long term memory will have a different requirement, when searching long term memory takes more than 10,000 milliseconds, delete 10 of the least access memories.&lt;br /&gt;&lt;br /&gt;Note: This means that the Ai’s memory will only be as good as it’s architecture. The faster the searching the more memory that the Ai can have in it’s short term memory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Action Memory&lt;/span&gt;&lt;br /&gt;Action memory records the chain of events that occurred from the data coming in to the motor response. It’s purpose is to help the Ai choose which evaluator to send sensor data to.&lt;br /&gt;&lt;br /&gt;Every time the Brain sends data to an Evaluator it will check to see if the sensor and evaluator exists in the Action memory:&lt;br /&gt;If it does not the Brain will insert a new row&lt;br /&gt;If it does, the Brain will increment the number of attempts&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;When an Evaluator receives data, during its processing it will:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Increment the understood column for all rows where the same sensor and evaluator are specified&lt;/li&gt;&lt;li&gt; If a row does not exist for the motor used, the evaluator will insert a new row with that motor in it.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The success rate is simply a calculation of attempts/understood.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Technical Note: The Action Memory table is not normalized (its flattened), this is intentional as the inserts will be few a frequent while the seeks or queries will be much greater. Thus this table needs to support quicker seeks. I will attempt to explain further later.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Memory Data&lt;/span&gt;&lt;br /&gt;For storing variable or relationships or even more complex “thoughts” there is data memory. It’s just a key, data paring. Which seems too simple. However, I think it would be the responsibility of the Evaluator to make sense of the “dirty” nature of the memory. I must admit that there is most likely a better solution. However keep in mind that this memory bank has to server a variety of functions and Evaluators.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;&lt;br /&gt;So all of this gives us the memory and storage of data. I would expect that storing this and accessing this would take up about 90% of the storage and processing capacity of our Ai brain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-7509780058826791673?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/skyqESG1CZ2I_JmuQ5LwD2iFjF0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/skyqESG1CZ2I_JmuQ5LwD2iFjF0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/skyqESG1CZ2I_JmuQ5LwD2iFjF0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/skyqESG1CZ2I_JmuQ5LwD2iFjF0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/dj8GiTB5z9M" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=7509780058826791673" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/7509780058826791673?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/7509780058826791673?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/dj8GiTB5z9M/artificial-intelligence-memory.html" title="Artificial Intelligence - Memory Management" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S6OpYBDjkbI/AAAAAAAAAB8/SrrMLHNY16s/s72-c/Ai+-+6.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/03/artificial-intelligence-memory.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQESXk5fip7ImA9WxBaFEs.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-6103687041751874635</id><published>2010-03-19T09:37:00.000-07:00</published><updated>2010-03-24T13:25:08.726-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-24T13:25:08.726-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Artificial Intelligence - The Brain</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S6Ooz0uYEeI/AAAAAAAAAB0/tr-33srUS5s/s1600-h/Ai+-+5.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 307px;" src="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S6Ooz0uYEeI/AAAAAAAAAB0/tr-33srUS5s/s400/Ai+-+5.PNG" alt="" id="BLOGGER_PHOTO_ID_5450385582328386018" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;So this picture paints the whole picture, except for the most important part, which is in the next post. But let’s make sure we have it all covered.&lt;br /&gt;&lt;br /&gt;Here’s how it works&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; When the “brain” is ready to start a new tas &lt;/li&gt;&lt;li&gt; It will remove the top item from the sensor stack&lt;/li&gt;&lt;li&gt; It will determine the best sensor (this is the unexplained important part)&lt;/li&gt;&lt;li&gt; The Evaluator will send commands to the motor stack&lt;/li&gt;&lt;li&gt; It will also send memory objects and requests to Memory Handler&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This continues till there is nothing to sense. We will talk about what the brain does when there is no data on the sensor, but not right now.&lt;br /&gt;&lt;br /&gt;So, we have a little gray area, but the picture is getting clearer right?&lt;br /&gt;&lt;br /&gt;Let’s continue…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-6103687041751874635?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_uFDLPfhPVbopvb8oHeAkiFXuI4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_uFDLPfhPVbopvb8oHeAkiFXuI4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_uFDLPfhPVbopvb8oHeAkiFXuI4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_uFDLPfhPVbopvb8oHeAkiFXuI4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/e8t09789xm8" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=6103687041751874635" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/6103687041751874635?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/6103687041751874635?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/e8t09789xm8/artificial-intelligence-brain.html" title="Artificial Intelligence - The Brain" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_MXZ6aBwP4Wo/S6Ooz0uYEeI/AAAAAAAAAB0/tr-33srUS5s/s72-c/Ai+-+5.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/03/artificial-intelligence-brain.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QEQHg6fSp7ImA9WxBaEkU.&quot;"><id>tag:blogger.com,1999:blog-5684424.post-39406932163143948</id><published>2010-03-12T13:32:00.000-08:00</published><updated>2010-03-22T11:08:21.615-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-22T11:08:21.615-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="game programming" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="lab" /><title>Artificial Intelligence - Evaluators</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_MXZ6aBwP4Wo/S5qzFaZGhOI/AAAAAAAAABs/QJWK3mDriiA/s1600-h/Ai+-+4.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 192px;" src="http://4.bp.blogspot.com/_MXZ6aBwP4Wo/S5qzFaZGhOI/AAAAAAAAABs/QJWK3mDriiA/s400/Ai+-+4.PNG" alt="" id="BLOGGER_PHOTO_ID_5447863604823360738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So we discussed how the Ai will sense the world and we have discussed how it will interact with the world. How will it bridge the gap and make intelligent interactions based on what it has sensed?&lt;br /&gt;&lt;br /&gt;Before we can cover that you have to understand that the Ai Brain is actually made up of a number of parts. Some folks would consider each of these parts as Agents or AI themselves. I will leave that debate to others that are wiser than me.&lt;br /&gt;&lt;br /&gt;For my purposes I call them Evaluators. The Ai Brain consists of many of them. Each Evaluator is responsible for performing the following:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; It takes data in, the data will always be in a rawest form&lt;/li&gt;&lt;li&gt; It attempts to understand this data&lt;/li&gt;&lt;ul&gt;&lt;li&gt; It will understand the data if it knows an motor action that can be given performed based on the input&lt;/li&gt;&lt;li&gt; Or it knows a memory object that needs to get created based on this action&lt;/li&gt;&lt;li&gt; Or it knows another evaluator that will understand this data&lt;/li&gt;&lt;/ul&gt;&lt;li&gt; If it knows a motor action to perform based on the input, it will place the motor action on the motor stack&lt;/li&gt;&lt;li&gt; If it knows a memory object that needs to get created it will create the memory object*&lt;/li&gt;&lt;li&gt; If it knows another evaluator that will understand this data it will pass this “suggestion” along. **&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Note that a sensor stack item may be sent to multiple evaluators. Some evaluators will be better at some things then others and usually there is a “best” evaluator for each type of data on the sensor stack. We will talk about this more later.&lt;br /&gt;&lt;br /&gt;Example evaluators:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Language evaluator - responsible for holding conversations&lt;/li&gt;&lt;li&gt;Math Evaluator – responsible for performing calculations&lt;/li&gt;&lt;li&gt;Image Evaluator – responsible for identifying an image&lt;/li&gt;&lt;li&gt;Knowledge Evaluator – responsible for identifying relationships between objects&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I would imagine that at some point the Ai brain may create its own evaluators by combining or altering existing evaluators. We will talk on this further as well.&lt;br /&gt;&lt;br /&gt;* See memory creation post (tbd)&lt;br /&gt;** See brain evaluator selection post (tbd)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5684424-39406932163143948?l=mobeamer.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Zjm0_oMMjeqirupKYGc_S16wHls/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Zjm0_oMMjeqirupKYGc_S16wHls/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Zjm0_oMMjeqirupKYGc_S16wHls/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Zjm0_oMMjeqirupKYGc_S16wHls/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mobeamer/~4/wfKh_swj9b0" height="1" width="1"/&gt;</content><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5684424&amp;postID=39406932163143948" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/39406932163143948?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5684424/posts/default/39406932163143948?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mobeamer/~3/wfKh_swj9b0/artificial-intelligence-evaluators.html" title="Artificial Intelligence - Evaluators" /><author><name>mobeamer</name><uri>http://www.blogger.com/profile/10810451912625092519</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_MXZ6aBwP4Wo/S5qzFaZGhOI/AAAAAAAAABs/QJWK3mDriiA/s72-c/Ai+-+4.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mobeamer.blogspot.com/2010/03/artificial-intelligence-evaluators.html</feedburner:origLink></entry></feed>

