How to delay xaml dialog on button click

When using a ContentDialog in UWP to allow the user to make some kind of action that depends on a service or other asynchronous call, you probably want to ensure that call completes correctly before dismissing the dialog window. Otherwise, the result is just forgotten about. In our UWP sample app, users can give gold to a particular photo they like and leave a comment. In the GiveGoldDialog the user inputs their comment text and then presses the “ok” button, which the app then fires off actions to handle gold balance transactions and creating the comment on the photo. Before dismissing the GiveGoldDialog, we wanted to be sure that those calls completed.

When handling the PrimaryButtonClick event, before initiating the actions get a ContentDialogButtonClickDeferral object from the ContentDialogButtonClickEventArgs parameter. Creating this deferral object will prevent the button click from finishing until you complete it, suspending(or canceling) the dialog from closing until your service call finishes. Based on your service’s actions, you can even stop the dialog’s button click from closing the dialog by setting the args’ Cancel parameter to true. This could be done to tell the user that the request wasn’t able to complete and try again or that maybe their content failed some kind of validation. In our sample app we would cancel the the action if the user’s gold balance was too low to complete the transaction.

async void Dialog_PrimaryButtonClick( ContentDialog sender, ContentDialogButtonClickEventArgs args )
  // Get the deferral because we need to await the
  // annotation to post.
  var deferral = args.GetDeferral();

  // Get creation status and if failed, let's
  // keep the dialog opened.
  var success = await ViewModel.MakeFooServiceCall();
  args.Cancel = !success;

  // Complete deferral to close the dialog.

When we originally wrote this code, the deferral object wasn’t very well documented and it took us some digging to figure out what it was and how to use it. Now it seems to be well documented within an example, but maybe this post will still help someone :)

ItemClicked event is not supported as an EventTriggerBehavior within ListItemTemplate

I’ve been working on writing some code samples for our Universal Windows Platform, they really are pretty neat how they enable a single app to run across Windows desktop, phone, Xbox One, and even HoloLens eventually. We’ll have the code sample released in the near future, but for now I wanted to blog about some small issues I’ve run into, couldn’t find any relevant documentation or stackoverflow answers, and I ended up figuring out the solutions on my own.
In this case, we were creating a listview and each item we wanted to be clickable to navigate to a detail page regarding that item. The listview control does have a selected item functionality built in, but we didn’t want to use that. A simple command to execute when one of the items is clicked is exactly what we wanted.
<DataTemplate x:Key="ListItemTemplate"> <interactivity:Interaction.Behaviors>
  <core:EventTriggerBehavior EventName="ItemClick">
      Command="{Binding DataContext.FooCommand, ElementName=LayoutRoot}"
      CommandParameter="{Binding}" />

<ListView ItemsSource="{Binding TheItems}"
  IsItemClickEnabled="True" SelectionMode="None"
  ItemTemplate="{StaticResource ListItemTemplate}" />
 Seems like this will get the job done, but compiler kept throwing us this very helpful error.
Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.EventTriggerBehavior' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection'. [Line: 27 Position: 95]
Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.InvokeCommandAction' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection'. [Line: 29 Position: 99]
Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.EventTriggerBehavior' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection'. [Line: 28 Position: 95]

Well, after a bit of digging I found out that a data template does not support an event trigger behavior for the event name as ItemClick. The ItemClick event is actually specific to the ListView xaml control, which is why the compiler complains that it cannot be added to the BehaviorCollection, so in our event trigger behavior we had to use a different event entirely. The Tapped event is the event we want, it is a high level event to cover both touch and mouse interactions.

<DataTemplate x:Key="ListItemTemplate">
      <core:EventTriggerBehavior EventName="Tapped">
            Command="{Binding DataContext.FooCommand, ElementName=LayoutRoot}"
            CommandParameter="{Binding}" />

<ListView ItemsSource="{Binding TheItems}
  IsItemClickEnabled="True" SelectionMode="None"
  ItemTemplate="{StaticResource ListItemTemplate}" />
 There we go. Now, when a user clicks, or touches, one of the items shown in the ListView, the proper trigger is fired.  Hope this helps!

Spring Form Tag Broken for Portlet Use

This issue came up as I was dealing with the Spring Portlet ResourceRequest change(before I found the problem/solution).  Still not getting the portlet to render views via ResourceRequests properly, I decided to test with Spring 3.2.x to see if the problem would follow.  I was also curious to see what changes would be made on the portlet side of things, any added improvements or shortcuts?  Based on the 3.2.x changelog, not much was changed regarding portlet support(ctrl+f “portlet”).  But its never that simple, right?

Enter SPR-8684.  This change actually makes things easy for most Spring webapps; automatically prepending the contextPath and servletPath in the Spring form tag is an easy shortcut.  But for portlets, this renders the form tag essentially useless.  Portlets don’t want their forms to be prepended with their own contextPath, they should resolve to the portal’s contextPath.  The good news is that my request for a fix was accepted almost instantly, SPR-10382.  So I’ll just have to wait to use Spring 3.2.3.

I know many of my most recent posts have been about problems using Spring, but I don’t want to sound like a complainer.  Without Spring I would be without a brilliant framework to code portlets with, and its a pretty niche area to be honest.  I love Spring because they are constantly moving forward by adding new ideas and technologies into their product.  Also, the community support is pretty fantastic!

Spring Portlet ResourceRequest Change

Spring Portlet made a change to the way portlets return resource requests.  They changed the default behavior of DispatcherPortlet when handling resource
requests to use PortletRequestDispatcher.forward instead of PortletRequestDispatcher.include; JIRA issue here — SPR-9876.  I’m indifferent about the change.  It seems more people use the ResourceRequest with the .forward, so its good for them I guess.  I mostly use resource requests with small custom jsps, so I use the .include.  But it doesn’t really matter to me aslong as they maintain compatibility, which they did.  If you set renderResourceViewViaInclude property to true(defaults as false) it should work the same as before.

Well, I can’t get my views to render through resource requests anymore after this change.  The only change that was supposed to be needed was adding an init-param into your portlet.xml, but even with that in place my views just return blank.


Another person also suggested to set alwaysInclude to true on the InternalResourceViewResolver in the applicationContext, but that didn’t work for me either.

<bean id=”viewResolver” class=”org.springframework.web.servlet.view.InternalResourceViewResolver”>
<property name=”cache” value=”false”/>
<property name=”alwaysInclude” value=”true”/>
<property name=”viewClass” value=”org.springframework.web.servlet.view.JstlView”/>
<property name=”prefix” value=”/WEB-INF/jsp/”/>
<property name=”suffix” value=”.jsp”/>

I’m still trying to figure out why this isn’t working.  Based on the git commit tied to the issue, it looks like aslong as renderResourceViewViaInclude is set to true then the dispatcher should call .include.  Is it not working as intended?  Or is renderResourceViewViaInclude not being set properly?

The culprit has been found! While talking with the person who made the JIRA issue and git commit, it looks like Spring never implemented the renderResourceViewViaInclude flag on DispatcherPortlet(and now rereading the last comment on JIRA I can see that they actually said they weren’t going to). So all resource requests were ALWAYS using .forward.  The fix?  You will have to subclass DispatcherPortlet and override doDispatch to use .include, or set up your own flag.

Hopefully Spring will actually put this the flag into the their portlet library so people won’t have to do this for every portlet that wants a review returned from a resource request.Talking with some other portlet developers, it seems I am in the minority of using resource requests to return views, they are mostly used to return pure json data.  It seems I either need to get with the times or I will have to use my subclassed DispatcherPortlet in all future portlets.

Spring Portlet Handler Mapping Error

Another post about Spring Portlet MVC.  Currently in Spring 3.1.2(and 3.1.1 as far as I can tell) there is a problem with portlet annotation handler mapping apparently due to a flaw in predicate comparison; its documented more in depth in their jira at SPR-9303.  The issue has been reported to have been fixed for Spring 3.1.3, but until that comes out I had to find a work around.

The hard part about diagnosing this bug is that it may or may not affect your portlet depending on how many annotation handlers you have, how they are structured, and in what order they are picked up by Spring.  Many of the portlets we have created haven’t had any problems(or none that we have experienced so far), but one portlet in particular was mapping every single render request to its default mapping.  Someone on stackoverflow has investigated the ordering further and shows exactly why the ordering matters.  Long story short, if the default handler mapping isn’t ordered last then any handler mappings behind it will never get used.

A workaround is simple enough, albeit a little ugly.  Remove the default annotation handler mapping method into its own class and package and have Spring component-scan to register it separately.  Like so:

<context:component-scan base-package=””>
<context:exclude-filter type=”regex” expression=”*”/>
<!– This package temporarily exists due to spring bug; SPR-9303 –>
<context:component-scan base-package=””/>

Doing this should scan and register the default mapping after everything else already has been.

Spring Portlet Validation Errors

I am currently in the process of updating some of our portlets to use Spring 3.1 and the new Portlet 2.0 spec in preparation with a portal framework upgrade taking place for ZotPortal this summer.  A problem we were experiencing using the new Spring 3.0 annotations for our portlets was the new way Spring handles validation/binding errors for forms.  Before, the validation is done in the action phase, then the error(s) are stored in the model attribute, and if errors are present you can redirect back to the render phase so the initial page form will be displayed again with the submitted data but this time displayed with error messages that explain to the user why it failed validation.  I was surprised when the validation would fail this time and redirect back to the page form but no errors would show.  Apparently something changed in the way Spring handles objects placed into the model via the @ModelAttribute annotation.  Now Spring would replace an object even if it is associated with errors and they will not be present/displayed when redirected back to the form.

A few solutions have been proposed across the spring forms, stackoverflow, and the interwebs;

  1. Validate the form object during the render phase as well.  This will generate the errors and have them displayed on the form when the rendering completes
  2. Explicitly preserve the form object or errors after the redirect and ensure they get passed to the form when rendering completes
  3. Instead of using @ModelAttribute, persist the form object as a session attribute so it persists across the action and render phases

Option 1 isn’t an option for our applications.  In the initial render phases the form object would not pass our validation tests because it isn’t filled out yet!  We don’t want to display validation error messages to the user upon the first load of the form when they haven’t had a chance to submit any data yet, it would seem a bit rude in my opinion.  Validation should occur if data has been submitted.  Option 3 seemed to be overkill, submitting a simple form shouldn’t need to persist the form object in the session which lives well past the action phase of the submit.  I believe Spring has some nice ways of handling these session attributes, but I haven’t played with it very much.

I decided to use option 2.  When the render phase is deciding what object to populate the form with it first checks to see if an applicable object with errors already exists in the model, if it does it lets that object stay in the model to populate the form.  The previous submitted data and errors get passed through the render phase and displayed on the form for the user to see and fix so it can be validated properly.

I wrote an example for persisting the object and it seems the same result can be accomplished by persisting the errors object instead, but I haven’t tested that.  Options 1 and 3 can also be found in this thread.

Social Networks

I’m a computer programmer.  I mostly program with java based web technologies, but I like to try my hand in all kinds of stuff.  Primarily being a web developer I can’t help but nickpick at websites when I’m browsing the web.  Most of websites are designed fairly well; you can usually navigate and use it without wasting too much brain power(Facebook).  Sometimes there are sites that are a bit confusing to navigate, but you can figure it out eventually(MLG).  Then there are the ones that it seem like they don’t have any actual content on their page, just terribly slow fancy effects(Xerox Real Business edit//looks like they’ve updated since I wrote this, good for them!).  The worst type are the sites that actually have content on them but are impossible to navigate(don’t have a current example of this, but the previous mlg website was pretty bad).

Besides considering the webpage layout/code itself, I also find myself thinking over the purpose of a website.  When I create a new web application I want people to have a reason to use it and to keep using it.  If they can get the same functionality somewhere else, I haven’t really accomplished anything.  Some web sites don’t really try to serve a particular purpose( while others do.  I specifically want to discuss social networks here.  What purpose does each one serve?  How come so many people have multiple social networks?  Do we really need another social network?  Is it accomplishing its purpose?  Who is actually using it?  Well I thought I’d do a write up of sorts to name the most current most popular.  Shout at me in the comments if there is one you want my thoughts on.

  • Facebook
    • Facebook has done everything right.  They captured our interest by being an exclusive group(at first) and offered us order from our terrible MySpace free-for-all-layouts.  Currently there is no alternative in my eyes(Google+ being the closest, more on that below) so everyone uses it and will continue to use it as they keep forcing new changes on us.  Now matter how much we complain they know we aren’t going anywhere.  The scariest part about facebook is that they make so much money off of us by selling our information.  Facebook isn’t the product in this scheme, we are.  You should always be careful what you put on the internet.  Just food for thought.
  • Goodreads
    • Goodreads is one of the newer social networks gaining ground.  It is a network centered around sharing books with your friends.  Fairly useful if you like to chat, share, and keep track of books with friends.  I’ve rather enjoyed using it.
  • Google+
    • Google+ is a fully functional social network, just without users.  In many ways it is better than Facebook, and Facebook took note of them and copied those features.  I use social networks to socialize with my friends but only a minuscule part of my friends use Google+, and that is why I don’t use it even though I think it is better designed.
  • Linkedin
    • Linkedin is marketed as a business related network, people connect with each other and create a sort of portfolio/resume via connections, employers, and projects.  However I’ve never personally encountered a use for that I actually was contacted for my job at Microsoft through Linkedin!  I can imagine the connections would be useful for finding jobs through old empoyees or recommendations.
  • MySpace
    • MySpace was the first Facebook, it held the monopoly on social networking at one point.  Its biggest fault was to give too much layout freedom to the users.  Too many MySpace pages were slow loading, hard-to-read, multiple-music-video-playing abominations.  Apparently it still survives as a more music related social network, but I don’t see how.  Its slowly dying from the stigma of its own past.
  • Pinterest
    • This is the newest social network I’ve encountered, and oh boy is it popular.  Personally I’m not sure why its so popular.  I have to give it credit since it has done a lot of things right to amp itself up–like be invite only to appear exclusive.  Here is my main beef with Pinterest: it offers no functionality that you cannot already do with almost any other social networking site.  What do you do?  You share pictures that you have either a) upload yourself or b) get from another user.  “But Kevin!  Pinterest makes it so much easier!”  Really?  I didn’t know the share button on any Facebook link or picture was that hard to use.  “But Kevin!  I can have all 9000 of my pictures in my profile all sorted into their respective categories!”  And do what with them?  Let them sit there that is what.  95% of the pictures I see on the internet I get a good laugh and move on.  4% I might keep open in a tab on chrome to read later in the week.  1% I will save in some fashion(save on reddit, share on Facebook, or post on my blog).  “But Kevin!  I found a great recipe that I need to keep on Pinterest so I can cook it later!”  Recipe book.  Write it down.  A+ for the name though.  It has a ring to it.
  • Tumblr
    • Tumblr is essentially a rebranded blog system.  It offers nothing new except this tumblrity feature that measures how many people have reblogged your content.  That’s cool I guess.  If someone reblogs my stuff I would hope they credit me somehow.  Again, my issue is with the network’s purpose being a duplicate of an already existing and functional social network(wordpress/blogger/any-other-blog-system).  If you didn’t catch on in my Pinterest rant I am bothered when something that offers no new functionality from what we already have captivates people as something totally new.  Tumblr to a lesser degree.  Pinterest is basically an even more boiled down version of Tumblr.  I see many people just using it as a blog and I would encourage them to use WordPress or even blogger.  More freedom and cooler plugins.  Also, the name is stupid.
  • Reddit
    • Reddit.  Where do I begin with Reddit.  I love it and I hate it.  It restores my faith in humanity and makes me realize how messed up we are.  I learn all sorts of interesting facts and waste hours scrolling through nothing.  I can’t think of another social network where I can read endless amounts of content from nearly every single subject that interests me.  One of the coolest things about Reddit is that it serves as a completely open and non-censored(apart from the illegal) content library.  You can post or read almost anything.  The oddest thing about reddit is how amazingly broad but eerily similar its user base is.  When the hivemind is in effect Reddit looses its appeal very quickly.  It is then that I become frustrated because this hivemind effectively censors that it disagrees with from being seen, which essentially goes against Reddit’s initial purpose.
  • Twitter
    • Twitter is something I see as the most misunderstood social network on the web.  They either miss the point of Twitter entirely or they just don’t think technology itself is very cool and that its going to corrupt your soul if you tweet where you are ate lunch.  One thing I don’t like about Twitter is that it is quickly becoming a library of idiots’ thoughts.  People are either making stuff up to appear cool/funny, complaining about mundane facts of life, or trying to make their hashtag trend(OH. EMM. GEE. I just got asked if I knew how to use powerpoint.  #mac4life #thingsthatartisticbarristasdealwithintheirdowntime)  On the whole I find Twitter very interesting.  It is one of the least structured social networks and while its only functionality is very similar to Facebook’s status updates, it serves a different purpose entirely.  It initially started out asking people to answer the question “What are you doing?” but has switched its question to “What’s happening?”(Twitter’s blog post regarding the matter).  A small change that had enormous impact on its purpose that I found fascinating.

My Motivation

Okay, I know this might be posted little bit late, but I loved this talk.

So much truth in who we are can be seen in our motivations.  Looking at my own I notice a number of things:

  • Creating software and web applications are not simple, straightforward tasks that can be completed without thinking.  Working software requires a lot of thought.  Furthermore, working software that is also well designed software is honestly more art than it is science.
  • I want to work on cool, interesting ideas.  Compensation isn’t the driving force here, I am.  I am passionate about programming.  I love it.
  • Motivation is more important than compensation.

Right now I am winding down in my first job search for after college.  It has been a fun journey with lots interviews, some let downs, a few surprises, and tons of experience.  When confronted with my end choices of possible employers, I’m not looking at where I could make the most money.  I’m looking at where I think I will get the most motivation and paid enough for my work. I don’t want to think about money, I feel like that is a waste of thought.  I want to think about my work, and create interesting things.  I am passionate about programming after all,  and not money.

Campus Organizations Portlet

As you know, I am currently programming web applications for the University of California Irvine.  I mainly work on web content for the student portal, ZotPortal.  If you aren’t too sure of what a web portal is, think iGoogle–lots of different content pieces all together in one place.  These content pieces are called portlets and I design, engineer, and maintain them on ZotPortal.  I want to talk about about two different things in this post, 1) a portlet I designed that enables people to search for on campus organizations at UCI and 2) some different ways of obfuscating email addresses(or other data) from potential spammers.  The connection will become apparent later.

Campus Organization Portlet

The Campus Organizations Portlet was the first portlet I built.  The idea was simple enough: given a feed of all the campus organizations, parse out the data, and display all the organization information in a searchable UI.  There are currently around 540 different organizations to show, so the data needed to be broken up into separate pages.  I decided to use the Fluid Pager javascript component to page through the data without having to reload the page.  This enables us to place each organization in its row along with its info box and category.  The gapped paging scheme makes navigating through the pages a breeze without cluttering the pager bar.  Some more javascript was added for to display organization info and the search bar to re-render the pager with just the search results.  All in all, the portlet is well put together and useful for finding clubs that interest you.

Now, on each organization’s information panel we supplied a mailing address so a user could contact the club leaders.  And since this portlet is accessible from the guest view, there is potential for spam bots to troll through our student portal and collect all of the club email addresses to sell or send spam to.  I wanted to hide the email addresses from the spammers while at the same time enable the viewer to use the email.  So, I spelled out the symbols in the email to confuse any would-be spam bots reading through my portlet data.  Instead of, coolclub[at][you see eye][period]edu.  An average spam bot wouldn’t recognize this as an email address, spam avoided!  The only thing that bothers me with this approach is the fact that the user has to do the work of replacing [at][you see eye][period] with”@uci.”.  Sure, it isn’t very difficult or time consuming, but it would be a lot better if the user could simply copy/paste or click a mailto tag.

I found someone in a similar dilemma and a really good answer was provided to him.  Examining these different methods of obfuscation allows us to pick the best one for our situation.

  1. CSS Codedirection
    • Coded
      • [code=’html’]moc.elpmaxe@zyx[/code]
    • Displayed
  2. CSS display:none
    • Coded
      • [code=’html’][/code]
    • Displayed
  3. ROT13 Encryption
    • Coded
      • [code=’javascript’]decodeROT13(klm@rknzcyr.pbz); [/code]
    • Displayed
  4. Using ATs and DOTs
    • Displayed
      • xyz[AT]example[DOT]com
  5. Building with Javascript
    • Coded
      • [code=’javascript’]var m = ‘xyz’;  m += ‘@’;  m += ‘’;  $(‘.email).append(m);[/code]
    • Displayed
  6. Replacing ‘@’ and ‘.’ with Entities
    • Coded
      • [code=’html’]xyz&amp;amp;amp;amp;#64;example&amp;amp;amp;amp;#46;com[/code]
    • Displayed
  7. Splitting Email with Comments
    • Coded
      • [code=’html’]xyzexamplecom[/code]
    • Displayed
  8. Urlencode
    • Coded
      • [code=’html’][/code]
    • Displayed
  9. Plaintext
    • Displayed

The author of this study (credit to Silvan Mühlemann; his original post can be found here) even watched of these methods for 1.5 years just to see the different amounts of spam each strategy would receive.  These were his findings…

Obfuscation Methods

The current obfuscating strategy I use received the lowest amount of spam out of the ones that got spam in this study, so it is an good choice.  However, there are better strategies, with zero spam, that don’t require any work from the user (strategies 1-3).  So I should change the strategy for obscuring the organization email in the portlet since there doesn’t seem to be any cost Late February 2011 we changed the obfuscating method and decided to use CSS direction.  We still are looking into a combination approach with CSS direction for display and javascript building for a mailto link for better and easier interaction.

AI Project: Checkers

To kick this Project site off I figure I’d start revisiting some work I did a couple quarters ago at UCI in an AI project course.  We set out to experiment with some different Checker strategies and see how they would fair against each other, against us, and (most importantly) against another team developing another Checkers AI system.  It was an interesting project to say the least.  I’ve created a simple game from my own ideas, but I haven’t created a game from a preexisting set of rules before or have the game play against the human.  The game system is pretty self explanatory; moves are hi-lighted, jumps are mandatory, a piece becomes a king on the other end of the board, and you win when you lose all your pieces or when you can’t make a move.  I really wanted to build this in something other than a Java applet, since they aren’t used much these days, but it was the closest and easiest tool to use for what I needed.  The AI depth search uses a min/max and alpha/beta pruning strategy to allow the massive move set to be shortened so a move decision can be made in reasonable time, but a search of depth 10 still makes a noticeable pause.

The most interesting part of this project is the AI strategies we implemented.

  • Random
    • The AI selects a move at random.  Hardly a challenge
  • Basic
    • The AI examines all possible moves within the search depth value.  It then selects the move that allows the AI to be in the position were losses and gains will be the most beneficial.  Ideally, the more pieces it can take and least amount of pieces it can lose will increase the probability to win the entire game.  This strategy is easily countered by tricking the AI with bait, and then trapping and taking its piece.  The best choice is based on an average score derived from a couple of heuristics.
      • Taking pieces(+ for regular; ++ for kings)
      • Loosing computer pieces(- for regular; — for kings)
      • Getting ‘Kinged'(+)
      • Moving a piece from a ‘King Me’ square(–)
  • Piece Table
    • In addition to the the heuristics above for the basic strategy, a piece table is also incorporated into the score for a move.  The piece table gives each square a value and it is added into the the average score for each move.  This is the piece table used for the Checkers game.  Each number denotes a square worth value.  The higher the value, the higher the worth of keeping a piece on that square.  Notice that all ‘King Me’ squares hold the highest value of 4, these spots are very important and a player would only want to move a piece from this location as a last resort.  Squares close to the sides of the board also have the value 4, and closer inside is 3, are the least vulnerable from attacks.  On the other hand, the squares in the very middle of the board hold a value of 1.  These squares get vacated as fast as possible since they are most susceptible from attacks.  The numbers make a sort of spiral from the outside, decreasing in value as they come closer to the middle.  This strategy is very strong since it combines the heuristics from the Basic strategy to minimize losses and maximize gains as well as achieve optimal piece placement on the board to further minimize more losses and maximize more gains.  I have not been able to beat this strategy.

Overall it was a very enlightening project to work on.  I learned a lot working with massive decision trees, different strategies, implementing given rules, and classifying data sets using a range of scores.  I was quite happy with the outcome of an AI that can easily beat its creator, and with the fact that we smoked the other Checkers project team.  Try your luck playing against it in the Code/Src tab.

I have a couple of planned changes for this application’s future:

  • Simplify the button options
    • The three buttons on the GUI made sense at the time I created them, but many users have reported that they have trouble knowing which one to click when.  Combining the Resign and New Game button into a single one will free space for an AI vs AI option.  Another problem is that when the Make AI Move button is pressed the player switches sides.  They have to click it again to resume play as the original red color.
  • Allow  the player to select his color at start of game
    • Just a nice option for the player to choose.