<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-3763625201879241628</id><updated>2009-12-02T19:28:42.936-06:00</updated><title type='text'>Mobile Games Development</title><subtitle type='html'>The journey of developing a set of mobile games and publishing them online for sale</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-1489413980415501808</id><published>2008-05-05T13:57:00.002-06:00</published><updated>2008-05-05T14:02:12.094-06:00</updated><title type='text'>AI The Third</title><content type='html'>The "expert" level of the Artificial Intelligence is ready (still to be debugged). The main algorithm is the same as the "intermediate" level. Calculate all the possible moves, evaluate the resulting position and make the move with the best ranking.&lt;br /&gt;&lt;br /&gt;The main difference is the evaluation routine which in this case consider many other things like the position where men are hit, the possibility of getting hit when leaving a bloat, the special scenario in which there's  no more contact possible, etc.&lt;br /&gt;&lt;br /&gt;I'm very happy of the way this is working because it could lead to great improvements in the quality of the artificial intelligence. Also because this algorithm could be applied to other games if I get it to consider several plies instead of just one. Of course this is not a simple thing, but hey, you have to start by the basics.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3763625201879241628-1489413980415501808?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/1489413980415501808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=1489413980415501808' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/1489413980415501808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/1489413980415501808'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2008/05/ai-third.html' title='AI The Third'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-3911159820232924007</id><published>2008-02-07T14:28:00.000-06:00</published><updated>2008-02-07T14:41:42.821-06:00</updated><title type='text'>Finally, some steps towards Internet Marketing</title><content type='html'>When I started this blog, I suggested I would explain how to market the end product online, but I also left clear I had no idea how to do that. Well, I've finally accomplished the first steps related to the marketing part. I still have a lot to learn regarding the subject, so if anyone is reading this blog and has some ideas I would love to hear them.&lt;br /&gt;&lt;br /&gt;So, how do we manage to sell anything online? There are several different options and all of them can happen at the same time, but one of the more attractive way I've found is through Affiliate Marketing. I came around a website called clickbank.com (OK, OK, I don't need to know everbody knows that site since last century, I just found it). The main idea of Affiliate Marketing is: 1) You develop a product and create a basic website promoting it and with a few specific features that "link" it to a third pary that's going to charge the customer and transfer the money to you; 2) You register yourself with that third pary, register your product in it and let it know the address of your "sales page"; 3) Some affiliates registerd with that third pary find your product intersting and create websites, articles, post advertising and so on making people go to your sales page; 4) When the customer purchases your product, a special tracking mecanism from the third pary determines the affiliate that drove the customer to your site and pays him a commission on your behalf. Of course it also takes a commission for itself and then pays you what's left.&lt;br /&gt;&lt;br /&gt;Obviously, in this case that third party is clickbank. Which by the way is absolutely free, so you don't have to spend a dime before really starting to sell. They'll only charge commissions after the sales and after issuing the payments twice a month (If you've sold anything at all :p).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3763625201879241628-3911159820232924007?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/3911159820232924007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=3911159820232924007' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/3911159820232924007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/3911159820232924007'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2008/02/finally-some-steps-towards-internet.html' title='Finally, some steps towards Internet Marketing'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-5207572709677925569</id><published>2008-02-07T14:16:00.001-06:00</published><updated>2008-02-07T14:27:54.905-06:00</updated><title type='text'>The Second AI Level... waaaaay better !</title><content type='html'>All right, I'm kind of excited because what I thought would be very difficult ended up being kind of piece of cake. The first level of AI was so stupid because it merely looked for the first valid move and that's it. The second level, which is almost finished except for a little bug fixing, is far better in concept.&lt;br /&gt;&lt;br /&gt;First, it creates an array of all the possible "combination of moves". With just this part of the definition it has two great advantages over the first level: considering all the possible moves and combining the moves allowed by each of the dice. This includes the possibility of moving the same man several times.&lt;br /&gt;&lt;br /&gt;But what would be the objective of having a list of possible moves if you're not going to "choose" the best of them. So the second part of the implementation is a "position evaluator". This is what makes me feel like I'm on the right track. Why? because all the implementations of chess engines have an algorithm that evaluates which one is the best among a list of valid moves.&lt;br /&gt;&lt;br /&gt;What does the position evaluator take into account? Well, so far, as positive for the rank, it considers the number of home board points that are blocked, the distance from the isolated men to the opponent's men, the advanced your men are, etc. on the negative side, the number of isolated men, the points with more than 5 men, etc.&lt;br /&gt;&lt;br /&gt;So it's unbeatable? ... I wouldn't say so. In fact, I would say it still plays fairly bad if you compare it to an experienced human player, but it will definitely have better odds than the first level. Specially if it has just a little luck. Besides, I had to leave room for the third and final AI level.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3763625201879241628-5207572709677925569?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/5207572709677925569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=5207572709677925569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/5207572709677925569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/5207572709677925569'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2008/02/second-ai-level-waaaaay-better.html' title='The Second AI Level... waaaaay better !'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-8838160322637441822</id><published>2007-12-07T16:08:00.000-06:00</published><updated>2008-02-07T14:15:43.495-06:00</updated><title type='text'>My first AI... Very "A", not "I" at all</title><content type='html'>My first Artificial Intelligence ever is ready, I don't think it qualifies as an AI since it doesn't learn, it's just a very basic "move evaluation and selection algorithm", but aren't chess engines the same thing??? Of course !!! you don't install your newly acquired ChessMaster and then "train" it submitting hundreds of thousands of highly selected games so it learns what is a good move and what is not.&lt;br /&gt;&lt;br /&gt;Why do we use the term Artificial Intelligence? I have not clue, so I thought, should I use "human vs phone" instead? I'm still thinking about it, but for the time being, I'm going with the flow of the industry and I have labeled it AI.&lt;br /&gt;&lt;br /&gt;What's even worst, as can be seen from the following code, my move evaluation and selection algorithm is not even that :(. It doesn't "evaluate" the possible moves and then "select" the best option. It just finds the first possible valid move and does it. It's very gratifying to watch the game answer your moves though. Even if the moves it does are absolutely dumb. I hope I can proudly label AI the second level when it's done, the first level should be labeled Artificial Stupidity...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(51,51,255);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;public byte[][] getMoves(Board board)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;byte moves[][] = new byte[board.getAvailableMovesCount()][2];&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.cloneBoard(board);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int currentMove = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for(int i = 0; i &lt;&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.availMoves[i] != 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;System.out.print(super.availMoves[i] + " ");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;System.out.println();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;label0:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(currentMove &lt;&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.barCount[board.getTurn() - 1] &gt; 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for(int i = 0; i &lt;&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.availMoves[i] == 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int point = board.getTurn() != 2 ? 24 - super.availMoves[i] : super.availMoves[i] - 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.boardColor[point] == board.getOpponent() &amp;amp;&amp;amp; super.boardCount[point] &gt;= 2)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;moves[currentMove][0] = -1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;moves[currentMove][1] = (byte)point;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;System.out.println("moving from " + moves[currentMove][0] + " to " + moves[currentMove][1]);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.barCount[board.getTurn() - 1]--;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.boardColor[point] != board.getTurn())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardCount[point] = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardCount[point]++;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardColor[point] = board.getTurn();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;currentMove++;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.availMoves[i] = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue label0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;return moves;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int j;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(board.playerCanBearOff())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;label1:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for(j = 6; j &gt; 0; j--)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int point = board.getTurn() != 2 ? j - 1 : 24 - j;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.boardColor[point] != board.getTurn())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int i = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(i &gt;= 4)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue label1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.availMoves[i] &gt; j)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;moves[currentMove][0] = (byte)point;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Board _tmp = board;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;moves[currentMove][1] = -2;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardCount[point]--;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.boardCount[point] == 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardColor[point] = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;currentMove++;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.availMoves[i] = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue label0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;i++;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;} while(true);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;j = board.getTurn() != 2 ? 23 : 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(board.getTurn() != 2 ? j &lt;&gt;= 24)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue label0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.boardColor[j] == board.getTurn())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for(int i = 0; i &lt;&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.availMoves[i] == 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int point = board.getTurn() != 2 ? j - super.availMoves[i] : j + super.availMoves[i];&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(point &lt;&gt;= 24  super.boardColor[point] == board.getOpponent() &amp;amp;&amp;amp; super.boardCount[point] &gt;= 2)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;moves[currentMove][0] = (byte)j;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;moves[currentMove][1] = (byte)point;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;System.out.println("moving from " + moves[currentMove][0] + " to " + moves[currentMove][1]);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardCount[j]--;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.boardCount[j] == 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardColor[j] = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(super.boardColor[point] == board.getOpponent())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardCount[point] = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardCount[point]++;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.boardColor[point] = board.getTurn();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;currentMove++;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;super.availMoves[i] = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;continue label0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;j += board.getTurn() != 2 ? -1 : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;} while(true);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;return moves;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;} while(true);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;font-size:130%;color:#000000;"&gt;P.D.: Even though the first level of the AI is absolutely stupid, it has managed to beat a couple of friends once or twice. Obviously they hadn't played the game before. So the skill level is not that inappropriate after all.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(51,51,255);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&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/3763625201879241628-8838160322637441822?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/8838160322637441822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=8838160322637441822' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/8838160322637441822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/8838160322637441822'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2007/12/my-first-ai-very-not-i-at-all.html' title='My first AI... Very &quot;A&quot;, not &quot;I&quot; at all'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-6359991697846426444</id><published>2007-12-07T15:15:00.000-06:00</published><updated>2007-12-07T15:47:23.557-06:00</updated><title type='text'>The importance of beta testing</title><content type='html'>Of course you can test your program yourself, you run it a thousand times when you're developing it testing small pieces of the code. But when you want to develop a first-class program without spending a lot of money, you need to ask some friends for their help in this annoying but very important task.&lt;br /&gt;&lt;br /&gt;It doesn't matter if you offer them a free copy of the final release, a couple beers, a free dinner (specially good idea if the beta tester in question is a girl you like), you will always find at least half a dozen friends willing to test your game. This will allow you to have different points of view regarding certain features and will expose your program to different environments. In this case, testing your mobile game against different phones is very important because they all use different screen resolutions and keyboard mappings.&lt;br /&gt;&lt;br /&gt;As of today, I haven't really figured out the best way to tackle those two problems: screen resolution and keyboard mappings.&lt;br /&gt;&lt;br /&gt;For the first one, I've made everything that's drawn in the screen adjust to a ratio of the total screen resolution, but that's more difficult when it comes to stored graphics because you need to choose a different image file depending on the resolution. It has come to my mind that I could make a "screen definition" file format that defines which image files to use and where to put them in the screen. It could also define font styles and sizes, colors and so on. This would not only make it very easy to setup a new screen resolution for a newly marketed mobile device but would also make the game "skinable", which would make a great feature altogether.&lt;br /&gt;&lt;br /&gt;About the keyboard mappings, I also think I should make a "keyboard configuration" option. That way, the user itself could choose what keys he wants to use for every action and the game would work with every possible device.&lt;br /&gt;&lt;br /&gt;As a proof of concept, and also to figure out the keyboard mappings of the phones a couple friends use, I developed a small Midlet that gives feedback of the keys as the user presses them. This is the code of the Canvas that does it all:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-size:85%;" &gt;&lt;span style="font-family: courier new;"&gt;import javax.microedition.lcdui.*;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import javax.microedition.lcdui.game.*;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import java.io.IOException;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import java.io.InputStream;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;class KeyTestCanvas extends Canvas {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    private int lastKeyCode;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    public KeyTestCanvas(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    protected void paint(Graphics g){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        int w = getWidth();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        int h = getHeight();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        g.setColor(0x000000);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        g.fillRect(0, 0, w, h);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        g.setColor(0xFFFFFF);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        g.drawString("keyCode:", 10,10,Graphics.TOP|Graphics.LEFT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        g.drawString(Integer.toString(lastKeyCode), 80,10,Graphics.TOP|Graphics.LEFT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        g.drawString("GameAction:", 10,30,Graphics.TOP|Graphics.LEFT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        try {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;            g.drawString(Integer.toString(getGameAction(lastKeyCode)), 80,30,Graphics.TOP|Graphics.LEFT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        } catch (Exception e) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;            g.drawString("Exception", 80,30,Graphics.TOP|Graphics.LEFT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        g.drawString("KeyName:", 10,50,Graphics.TOP|Graphics.LEFT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        try {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;            g.drawString(getKeyName(lastKeyCode), 80,50,Graphics.TOP|Graphics.LEFT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        } catch (Exception e) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;            g.drawString("Exception", 80,50,Graphics.TOP|Graphics.LEFT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    protected void keyPressed(int keyCode){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        lastKeyCode = keyCode;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        repaint();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}&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/3763625201879241628-6359991697846426444?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/6359991697846426444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=6359991697846426444' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/6359991697846426444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/6359991697846426444'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2007/12/importance-of-beta-testing.html' title='The importance of beta testing'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-2633663535500150457</id><published>2007-11-12T09:21:00.000-06:00</published><updated>2007-11-12T10:01:25.062-06:00</updated><title type='text'>FYI: Computer Scientists Are NOT Artists</title><content type='html'>Everyone expects, and should expect, programs to look nice, to have User Interface elements arranged in ways that make it easy to use, to include cool images that match the general color theme (taking for granted the program will have a "general color theme" and not all the colors of the rainbow used inconsistently over the different screens).&lt;br /&gt;&lt;br /&gt;Of course this is the case if you use a computer game. The company that produced it spent tens of thousands of dollars, perhaps even more, in the game presentation and art. However, when you try to develop a mobile game in your garage (or in your bedroom as in my case), spending as much as $100 in the art of your game can be very painful.&lt;br /&gt;&lt;br /&gt;I think the first consideration you have to make is whether you are developing the game just for the fun of doing it or you're actually considering to publish it either free or not. Even if you don't plan to charge for the game, if you publish the game it should look professional. I've downloaded dozens of poorly developed games and I always make sure not to go back to that site. I'm sure you don't want your name in the credits of a game that looks like a 5 year old drawing.&lt;br /&gt;&lt;br /&gt;But then, who do you get your game to look professional without spending a lot of money? ... well, my first advice is to emulate professionally developed games. You can download hundreds of free games and trials and look for the characteristics you want for your game. Playing lots of different games will help you determine how you game should look and behave and, even more important, how your game should NOT look and behave. WARNING: of course I'm not suggesting you copy other games! It's not only immoral and illegal, It'll make you look like a loser. What I'm suggesting is to look at the distribution of user interface items, the flow of the screens, the usage of forms, etc. and then implement your game using those elements as guidelines.&lt;br /&gt;&lt;br /&gt;The second advice comes from the subject of the post. Ask for help from a non-it person. Hopefully from a graphics designer or someone in a similar industry, but at least from a very well tasted and innovative person. You'll find that even if the person you talk to doesn't suggest color schemes and graphics you like, discussing the subject with them will let yourself identify the type of look and feel you want for your game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3763625201879241628-2633663535500150457?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/2633663535500150457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=2633663535500150457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/2633663535500150457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/2633663535500150457'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2007/11/fyi-computer-scientists-are-not-artists.html' title='FYI: Computer Scientists Are NOT Artists'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-6203836766835098849</id><published>2007-11-09T17:03:00.000-06:00</published><updated>2007-11-12T09:21:09.312-06:00</updated><title type='text'>Trial And Error, Not Precisely The Best Alternative</title><content type='html'>All right, trying to learn a new technology all by yourself may not be the easiest thing in the world, but when you've developed java applications of almost any kind, learning to use a new API isn't really complicated. What actually makes it complicated is not taking a few hours to RTFM!!!&lt;br /&gt;&lt;br /&gt;Once I realized I had the ability to write some code, compile it and run it in the Wireless Toolkit simulator I just jumped right into the development stage. Wrong idea !!!&lt;br /&gt;&lt;br /&gt;MIDP is not a huge/complicated API. However, I strongly recommend reading as much information about the usage of the basic classes and specially about the best practices involved. Getting a good idea of when to use separate threads; when to use a Canvas, a Game Canvas or a Form; when to implement CommandListener and where... these are all things you should know about before starting your project.&lt;br /&gt;&lt;br /&gt;I ended up writing a complete mess, then wisely decided to start over, managed to write another mess even bigger, once again wisely decided to start over and finally came up with a decent implementation. The first two attempts did work, they showed the game and allowed you to play, but moving from one Canvas to another or handling user commands was a complete pain. The third attempt on the other hand was very very clean, with very few lines of code and allowed me to add features and change the behavior of the game very easily.&lt;br /&gt;&lt;br /&gt;There's just one thing I still don't understand... Why haven't I read about the things I'm suggesting to read?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3763625201879241628-6203836766835098849?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/6203836766835098849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=6203836766835098849' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/6203836766835098849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/6203836766835098849'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2007/11/trial-and-error-not-precisely-best.html' title='Trial And Error, Not Precisely The Best Alternative'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-4719966172527741616</id><published>2007-11-08T08:58:00.000-06:00</published><updated>2007-11-08T09:22:49.984-06:00</updated><title type='text'>The Tools</title><content type='html'>No programmer can call himself a real programmer if he/she can't program without a fancy IDE that points out syntax errors, provides code templates and code completition, compiles (and links if it applies) automatically, and so on. Once you can write your program in notepad or vi and create your executable files through command line compilation you can say you really know the language and the tools... but dang it's annoying!!!&lt;br /&gt;&lt;br /&gt;Since I had never programmed using MIDP, I didn't even know what libraries and tools were necessary, so I went to the first place that comes to everyone's mind... Google. I was bound to be directed to the java.sun.com site anyway, but Google can take you to the right page with fewer clicks.&lt;br /&gt;&lt;br /&gt;At the java site I found out about the Sun Java Wireless Toolkit (version 2.5.1) at that moment. The current version at the time of this writing is already 2.5.2. So I downloaded it, installed it, compiled and ran a couple examples and I knew I was pretty much set... Yeah right!&lt;br /&gt;&lt;br /&gt;Even though I was able to start the project, create a couple Canvas and implement the basic human vs human game, having to edit your java files in notepad is not the easiest way. After some days programming that way I thought it was time to get a decent IDE. So I downloaded NetBeans 5.5.1 and the Mobility Pack which allows you to create MIDP projects.&lt;br /&gt;&lt;br /&gt;Now that's what I'm talking about! With all the bells and whistles you can ask for, and then some, you can comfortably develop your project with absolute integration with the Wireless Toolkit for compilation, execution and debugging. I'm so glad I took the time to research about IDEs for wireless development. I definitely recommend the combination of NetBeans and its Mobility Pack to anyone that wishes to develop mobile applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3763625201879241628-4719966172527741616?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/4719966172527741616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=4719966172527741616' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/4719966172527741616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/4719966172527741616'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2007/11/tools.html' title='The Tools'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3763625201879241628.post-5601965139097473145</id><published>2007-11-07T10:27:00.000-06:00</published><updated>2007-11-08T09:23:15.984-06:00</updated><title type='text'>How It All Got Started</title><content type='html'>I've always liked cell phone games. The first mobile phone I had was a Nokia 952 and I loved snake. It was a great help when you arrived too early to a meeting and had to wait for a while.&lt;br /&gt;&lt;br /&gt;Now, I know cell phones started supporting java based games several years ago, but I never thought on making one. However, about a couple weeks ago, a co-worker told me he had been looking for a free Backgammon for his cell phone and had not found any. I figured I could do one fairly easily and, with some luck, even make some money out of it.&lt;br /&gt;&lt;br /&gt;Why I'm I writing about this? ... well, I don't really know. I guess you guys can suggest great features for the games I end up developing and can even buy some of the games. I think it can help other people overcome the obstacles I find along the way too. So far, I'm concerned of how I will send the end product to the customer in a secure way and without allowing piracy to eat my business. I'm also concerned of how to charge the customer and receive the money. Since I'm from and live in El Salvador, getting money online to my bank account can be quite difficult.&lt;br /&gt;&lt;br /&gt;Anyway, if everything works out as planned, I will end up having a set of fully functional, first quality, fun packed mobile games. I will also have everything set up for them to be sold online (hopefully without spending more money than I get in the process). Even if it doesn't work quite as planned, I know it'll be a lot of fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3763625201879241628-5601965139097473145?l=mobilegamesdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mobilegamesdev.blogspot.com/feeds/5601965139097473145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3763625201879241628&amp;postID=5601965139097473145' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/5601965139097473145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3763625201879241628/posts/default/5601965139097473145'/><link rel='alternate' type='text/html' href='http://mobilegamesdev.blogspot.com/2007/11/how-it-all-got-started.html' title='How It All Got Started'/><author><name>Mauricio Peccorini</name><uri>http://www.blogger.com/profile/10398199808210027262</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17938373786921539266'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>