I've had my Windows Phone for over a month. (I went from the Lumia 710 to 800 as my 710 was faulty. The 800 is better in every way.) Here's a list of apps that I'm using.
Wordament: Boggle where you compete against everyone else playing the game at the same time. Really well implemented and completely addictive. Having that "you vs the Internet" is an excellent feature. I can play in Spanish now too. Genial. Free
NextGen Reader: Superb RSS reader. Best I've used on any device. $2.50
AU Weather Pro: Australia only, but best weather app I've used on either WP7 or iOS. I love the customisable live tiles! I have current temperature plus 2 day forecast on one side, and radar on the other side. $3
Call Credit: It tracks your call and data use. Works really well. Free
YouTube Download: Download any YouTube video so you can replay it whenever you want. $1
Skype: Finally out of beta. It works but it's a bit naff. Needs integrating with the OS. Needs to sort by online/offline. Needs to run in the background. Disappointing. Free
Nokia Drive: Occasionally gives the wrong advice, but generally very good. Free
Amazon Kindle: Works fine. Free
Facebook: A bit slow and a bit redundant (Facebook is basically already part of the OS). Free
Flickr: Works fine. I wish this was fully integrated into the Pictures app of the OS. Free
Office: Only time I've used this is when I needed to read my brother's Word document that he sent to me. It was all formatted really well, including images. Free
iStunt 2: Fun little game. Free (for trial version)
Skydrive: Like Dropbox but way more space. Free
Monday, April 30, 2012
Tuesday, March 20, 2012
Comments on Windows Phone

I've completely changed the default layout to be entirely people centric rather than app or service centric. It makes people with iPhones look like geeks. This came from Microsoft! Inconceivable!
Things I like:
- Metro UI. It's taking over the whole Microsoft design world. It's superb. It looks good and easy to use. Someone really needs to apply it to computer games (I'm not talking about GUI in games, but the games themselves. Imagine a FPS in a Metro style!)
- Unobstrusive. I don't like how iOS interrupts my activity with irrelevant messages.
- Linking to all my accounts was simple. Way easier than setting up my Google mail account on the iPad, for example.
- Very responsive. It loads apps very quickly. It doesn't have the clunk of iOS (and it's not even multi-core yet).
- It's a social OS. My phone revolves around people rather than mediums (calls, SMS, email), services (Facebook, LinkedIn) or apps (pictures, music, etc.)
- The base apps are really good. E.g., Nokia Drive, Office, Xbox games.
- The back button is really useful.
- Animation on the people tiles. These tiles should not change unless I have a new message. I know who the person is by their picture, I don't need the OS to switch between their picture and their name. Bad user experience Microsoft! (But it's the only poor decision I've seen thus far.)
- The link between a person and their e-mails doesn't work correctly. On a person's profile it will say I've received emails from them. When I click to see the list it lists all emails, not the emails coming solely from them. Surely this isn't an uncommon use case! Weird.
- I'm not convinced that the screen-size is large enough to use the keyboard effectively. I feel like I'm getting more typing errors than I'd expect. This could be an OS issue, screen issue, general issue with smart-phones or a me issue.
- Needs Skype integration. (Microsoft, you might not have noticed that you own Skype!)
- Needs Google+ integration. I know few use it, but most of my geeky friends do.
- The search button uses Bing. (Useless)
Labels:
iPad,
Microsoft,
Nokia,
review,
Windows Phone
Thursday, March 8, 2012
Computer Reversi, Part 1.5: The Thor database (Othello tournament files)

My initial motivation for finding an archive was to have a easy way to unit test my code to ensure it implemented the Reversi rules correctly. If the game engine could play through 100,000 games and calculate the final score, that's a good indication that the rules have been implemented correctly. An archive can also be used for book openings. I have another idea for the archive too, which I will hopefully reveal soon.
My Reversi source code has a Thor project with a bunch of methods and classes for extracting the data for whatever nefarious needs you may have. I don't think there is any code in C# on the net for this, so maybe one day it'll be helpful for someone. Maybe. (Probably not.)
The file format documentation is challenging to understand because it is written in French. I have translated (thanks to Nuz and google translate) the core elements of the document in the section below. The aspects I found challenging were:
- Interpreting the meaning of the black player's score (I needed to calculate the score as the final check to ensure my rules were working)
- Interpreting the way they recorded the individual plays
- Converting elements of a byte-array to a 16-bit integer. (The data are stored as little-endian. One way: BitConverter.ToInt16(new [] { thorArray[i], thorArray[i + 1] }, 0).)
- Get sum of black pieces and the sum of white pieces;
- Whoever has the most pieces wins;
- The winner adds to the sum the number of empty squares;
The data, such as Word and Longint, are stored in Intel format, ie the lowest byte first. There is a game file for every year. Games are stored in any order, but normally grouped by tournament.
Database header fields
All files in the database Wthor have a header of 16 bytes, followed by a number of game records all having the same size. The header consists of the following fields:
- Century file was created
- Year file was created
- Month file was created
- Date file was created
- Number of records N1
- Number of records N2
- Year of game
- Parameter P1: size game board
- P2 parameter: type of games
- Parameter P3: depth
- X1 (reserved)
- Tournament Number
- Number of Black player
- Number of White player
- Number of black pieces (true score)
- Theoretical score
- Move list
Tournament file
Player file
Each record (20 bytes) is an array of characters terminated by a binary zero. The effective length is 19 characters. There is a 16 byte header for this file.
Labels:
c#,
programming,
Reversi
Monday, March 5, 2012
JavaScript - Accessibility and Useability
There has been talk at work about having to provide non-JavaScript alternatives for any of our web-pages that use JavaScript. A few people were suspicoius of this idea and given that we're using MVC3, they were finding it very difficult to implement functionality without JavaScript. Below is the document I created after reading compliance info on the net. You can also download as a Word doc.
JavaScript - Accessibility and Useability on the Web
Below are the relevant sections of documents concerning
JavaScript and its impact on website accessibility and useability. I have checked
documents relating to accessibility compliance under Australian law, compliance
for US law and more general accessibility sites. In the conclusion, I explain a
public website’s responsibilities regarding JavaScript and accessibility/useability.
Disability Discrimination Act Advisory Notes
It is important for developers to
understand that in many cases the accessibility of a particular technology will
be determined by how it is used. For example, it is widely considered that
JavaScript can be implemented so as to be accessible. However, JavaScript can
also be used in ways that are inaccessible, particularly if full keyboard
support is not provided.
Ten Common Web Accessibility Failures
Ten Common Web Accessibility Failures
1. Failure to include appropriate text
descriptions (such as “alt-text” labels) for images;
2. Failure to provide accessible alternatives
when using a visual CAPTCHA;
3. Failure to use technologies (such as Flash
and JavaScript) in ways that are accessible;
4. Failure to use HTML features appropriately
to indicate content structure such as the hierarchy of headings;
5. Failure to explicitly associate form input
controls with their labels;
6. Failure to ensure sufficient difference
between foreground (text) colour and background colour;
7. Failure to identify data tables with Summary
or Caption, and failure to mark-up data tables correctly;
8. Failure to provide a way for users to
disable content such as advertisements from flashing rapidly (rapidly-flashing
content may cause seizures in susceptible individuals), and failure to provide
a way for users to stop a page from auto-refreshing;
9. Failure to ensure that web pages can be used
from the keyboard (that is, without the mouse);
10. Failure to alert the user to changes on a
web page that are triggered automatically when selecting items from a dropdown
menu.
How to Meet WCAG 2.0
1.1 Text Alternatives: Provide text
alternatives for any non-text content so that it can be changed into other
forms people need, such as large print, braille, speech, symbols or simpler
language.
1.2 Time-based Media: Provide alternatives for
time-based media.
1.3 Adaptable: Create content that can be
presented in different ways (for example simpler layout) without losing
information or structure.
1.4 Distinguishable: Make it easier for users
to see and hear content including separating foreground from background.
2.1 Keyboard Accessible: Make all functionality
available from a keyboard.
2.2 Enough Time: Provide users enough time to
read and use content.
2.3 Seizures: Do not design content in a way
that is known to cause seizures.
2.4 Navigable: Provide ways to help users
navigate, find content, and determine where they are.
3.1 Readable: Make text content readable and
understandable.
3.2 Predictable: Make Web pages appear and
operate in predictable ways.
3.3 Input Assistance: Help users avoid and
correct mistakes.
4.1 Compatible: Maximize compatibility with
current and future user agents, including assistive technologies.
(No
specific mention of JavaScript.)
Migrating from WCAG 1.0 to WCAG 2.0
Ensure that pages are usable
when scripts, applets etc are turned off or not supported. If this is not
possible, provide equivalent information on an alternative accessible page.
[Priority 1]
|
NO MATCHING WCAG 2.0 S.C.
Issue is addressed as part of
"Conformance requirements".
|
NB: WCAG 2.0 does not require
alternative to be always provided for JavaScript etc. But nominated
"accessibility supported technologies" must be used in a way that
is accessible.
Conformance requirement 4: Only accessibility supported
technologies are relied on to satisfy the success criteria. AND
Conformance requirement 5: If technologies that are not
accessibility supported are used, they do not stop users accessing the rest
of the page.
|
Accessible Rich Internet Applications (WAI-ARIA) 1.0
New
technologies often overlook semantics required for accessibility, and new
authoring practices often misuse the intended semantics of those technologies.
Elements that have one defined meaning in the language are used with a
different meaning intended to be understood by the user.
For
example, web application developers create collapsible tree widgets in HTML
using CSS and JavaScript even though HTML has no semantic tree element. To a
non-disabled user, it may look and act like a collapsible tree widget, but
without appropriate semantics, the tree widget may not be perceivable to, or
operable by, a person with a disability because assistive technologies may not
recognize the role.
Screen readers vs JavaScript
JavaScript Enabled = 98.4%,
Disabled = 1.6%
10.4% of respondents to the October
2009 survey indicated that they have JavaScript disabled in their web
browser. As respondents submitted responses to this survey we detected the
presence of JavaScript. We found that very few respondents had it disabled or
unavailable in their web browser. Of the 19 respondents with JavaScript
disabled, 12 were using Firefox (presumably with the NoScript add-on enabled)
and 5 were using Lynx with Linux.
Creating Accessible JavaScript
Making JavaScript accessible involves looking
at the following issues. Each of these will be discussed in the next lessons.
·
When
using event handlers, use only those that are device independent (e.g., do not
require the use of the mouse only).
·
Content
and functionality that is provided through scripting must be made accessible to
assistive technologies.
·
Web
pages that utilize scripting must be fully navigable using a keyboard.
·
JavaScript
should not modify or override normal browser functionality in a way that may
cause confusion.
·
When
JavaScript cannot be made natively accessible, an accessible alternative must
be provided.
Accessible forms: Guidelines, examples and accessible JavaScript tricks.
So what will you find here?
·
A list of form guidelines based on current and
on-going research into accessibility, usability and web standards.
·
Simple examples of accessible forms including: a
login form, a search form and a contact form.
·
Examples and help on each form element.
·
Styling forms with CSS.
·
Using accessible inline JavaScript to aide form
functionality.
·
Using accessible JavaScript with the DOM to aide
form functionality.
·
A comprehensive list of external form related
articles and resources.
Conclusion
W3C,
Australian law and US law either make no comment on JavaScript or state that
JavaScript is acceptable as long as accessibility is maintained.
WCAG 1.0
required that non-JavaScript alternatives were required. WCAG 2.0 does not have
this requirement. In compliance with WCAG 2.0, we are permitted to implement
pages that would not be useable without JavaScript so long as they remain
accessible.
The
guidelines at http://webaim.org/techniques/javascript/ and http://www.websemantics.co.uk/tutorials/accessible_forms/
can assist in determining how
to ensure the use of JavaScript on a website is accessible.
Labels:
JavaScript,
MVC,
programming
Tuesday, February 28, 2012
Computer Reversi, Part 1 (Or how I learned to stop worrying and love the bits)
After noughts and crosses I thought I’d try Reversi (Othello). Reversi has simpler rules than chess but remains complex enough that it hasn’t been mathematically solved, yet.
I thought I’d find a wealth of information on the net about how to program a Reversi game. However, there wasn’t all that much out there. I found some helpful blog entries at Red Alt Blog. I used that as my starting point.
The best resource for understanding how to program Reversi is at the chess programming wiki. They have an Othello page as well as pages that helped me do a bitboard version of Reversi, with move generation and resolution (dumb7fill), population count (i.e., number of bits on the board) and board serialisation (using bitscans). I'm hoping it'll also be helpful for position evaluation later on.
The tasks needed to code a Reversi computer game with a learning computer opponent are
The following sections describe some interesting parts of the source code, relating with the first six steps outlined above.
Reading the source code
The entry point for the application (the Main method) is the Start method of the GameBehaviour.cs file. This file is attached to the main camera in Unity. The GameBehaviour.cs file creates the board and pieces as 3D objects and hosts an instance of GameManager (see below). It also manages the UI controls to save/load games, undo/redo moves, setup the human/computer players, start a new game, etc.
The files that do all the real work are:
GameManager
The GameManager class does the work-a-day tasks of the game. Tasks such as:
My GameState class handles most of the game rules of a Reversi game. You pass it two unsigned 64-bit integers (ulong in C#). These numbers are a bitboard representation of the game. The first number represents the current player's pieces. The second number represents the opponent's pieces. E.g., the starting position for black is represented as 0000000000000000000000000001000000001000000000000000000000000000 in binary. When you lay out those zeros and ones on an Reversi board, you get:
Why represent the pieces like this? Bitboards appear to have advantages over other board representations. They appealed to me because I often feel withdrawn from the goings on of the computer. Bitboards were a chance to get in closer to the CPU and play around with individual bits.
One interesting aspect of the GameState class is that it is temporally agnostic. It doesn't know what turn of the game it is. It doesn't even know whose colour is to play next. All it cares about is that it is someone's turn and it figures out where they can play and what happens to the board once they do. I like the simplicity of not needing to deal with time.
The GameState class will tell you if the game is over and whether the current player has won.
BitBoardHelper
I created a BitBoardHelper class to add some extension methods to my ulong bitboards. These methods allow me to count the number of bits, find the indices of the bits and find the unoccupied bits of any two bitboards. I'll probably expand this class when I work on the computer opponent.
For finding the indices (bitboard serialisation) I used the De Bruijn method to do the bitscanning. For the bit count (population count) I used the SWAR Popcount routine.
Play
There is a Play class in the project that will find all the valid moves for the current player and also resolve a chosen move (i.e., flip of the pieces that need to flipped once a piece has been played). The basic idea is to focus one direction (cardinal or ordinal) at a time, scanning 8 locations in parallel. Red Alt explains it well (see under the bitboard heading). Once I could detect where a player could place a piece, I used a very similar method to resolve that move. This class is called by the GameState class and is only different to the BitBoardHelper class in that it has specifically Reversi functionality.
Graphic User Interface
The GUI uses the Unity 3D graphics engine. Much of the code that I use in the Reversi project is a simpler version to what is found in a previous article on Unity and path-finding. Unity displays the board and captures user input.
Save/load games and undo/redo moves
Save/load and undo/redo are interrelated. To do them, I need to keep track of the moves made by the players. If I do that, I can:
In Part 2, I intend to cover the aspects of creating a computer opponent for Reversi. The primary goal is to be able create an opponent that can beat me in a game. (Not a highly goal.) Hopefully, I'll be able to have it beat all but the best Reversi players.
I thought I’d find a wealth of information on the net about how to program a Reversi game. However, there wasn’t all that much out there. I found some helpful blog entries at Red Alt Blog. I used that as my starting point.
The best resource for understanding how to program Reversi is at the chess programming wiki. They have an Othello page as well as pages that helped me do a bitboard version of Reversi, with move generation and resolution (dumb7fill), population count (i.e., number of bits on the board) and board serialisation (using bitscans). I'm hoping it'll also be helpful for position evaluation later on.
The tasks needed to code a Reversi computer game with a learning computer opponent are
- Game state representation
- Move generation
- Move resolution
- Determine game over and winner
- Graphic User Interface
- Save/load and undo/redo moves
- Position evaluation (i.e., fitness/objective function)
- Depth-first search algorithm (e.g., mini-max or nega-scout)
- Book/database based analysis (e.g., opening book, transposition tables)
- Mathematical optimisation (e.g., simulated annealing or genetic algorithm)
The following sections describe some interesting parts of the source code, relating with the first six steps outlined above.
Reading the source code
The entry point for the application (the Main method) is the Start method of the GameBehaviour.cs file. This file is attached to the main camera in Unity. The GameBehaviour.cs file creates the board and pieces as 3D objects and hosts an instance of GameManager (see below). It also manages the UI controls to save/load games, undo/redo moves, setup the human/computer players, start a new game, etc.
The files that do all the real work are:
- GameBehaviou.cs
- GameManager.cs
- GameState.cs
- BitBoardHelper.cs
- Play.cs
GameManager
The GameManager class does the work-a-day tasks of the game. Tasks such as:
- Save/load
- Undo/redo
- Tells you whose turn it is
- Tracks the list of plays
- Tracks the turn number
My GameState class handles most of the game rules of a Reversi game. You pass it two unsigned 64-bit integers (ulong in C#). These numbers are a bitboard representation of the game. The first number represents the current player's pieces. The second number represents the opponent's pieces. E.g., the starting position for black is represented as 0000000000000000000000000001000000001000000000000000000000000000 in binary. When you lay out those zeros and ones on an Reversi board, you get:
Why represent the pieces like this? Bitboards appear to have advantages over other board representations. They appealed to me because I often feel withdrawn from the goings on of the computer. Bitboards were a chance to get in closer to the CPU and play around with individual bits.
One interesting aspect of the GameState class is that it is temporally agnostic. It doesn't know what turn of the game it is. It doesn't even know whose colour is to play next. All it cares about is that it is someone's turn and it figures out where they can play and what happens to the board once they do. I like the simplicity of not needing to deal with time.
The GameState class will tell you if the game is over and whether the current player has won.
BitBoardHelper
I created a BitBoardHelper class to add some extension methods to my ulong bitboards. These methods allow me to count the number of bits, find the indices of the bits and find the unoccupied bits of any two bitboards. I'll probably expand this class when I work on the computer opponent.
For finding the indices (bitboard serialisation) I used the De Bruijn method to do the bitscanning. For the bit count (population count) I used the SWAR Popcount routine.
Play
There is a Play class in the project that will find all the valid moves for the current player and also resolve a chosen move (i.e., flip of the pieces that need to flipped once a piece has been played). The basic idea is to focus one direction (cardinal or ordinal) at a time, scanning 8 locations in parallel. Red Alt explains it well (see under the bitboard heading). Once I could detect where a player could place a piece, I used a very similar method to resolve that move. This class is called by the GameState class and is only different to the BitBoardHelper class in that it has specifically Reversi functionality.
Graphic User Interface
The GUI uses the Unity 3D graphics engine. Much of the code that I use in the Reversi project is a simpler version to what is found in a previous article on Unity and path-finding. Unity displays the board and captures user input.
Save/load games and undo/redo moves
Save/load and undo/redo are interrelated. To do them, I need to keep track of the moves made by the players. If I do that, I can:
- Save: Write the move list to the hard drive.
- Load: Read the move list from the hard drive, start a new game, apply move list - one move at a time - until the last move is applied.
- Undo: Start a new game, apply move list until the desired turn (similar to load).
- Redo: Identical to undo.
In Part 2, I intend to cover the aspects of creating a computer opponent for Reversi. The primary goal is to be able create an opponent that can beat me in a game. (Not a highly goal.) Hopefully, I'll be able to have it beat all but the best Reversi players.
Labels:
c#,
Computer games,
programming,
Reversi,
Unity
Friday, January 20, 2012
Google Translate
Google Translate works quite well. Occasionally it does some weird things. For instance, it translates (from Spanish)
That is exactly what I'd expect it to say. However, when I change it by one word,
No me acuerdo bien cómo me aparecìa.
to
I do not remember exactly how I appeared.
That is exactly what I'd expect it to say. However, when I change it by one word,
No me acuerdo muy bien cómo me aparecìa.
I get
I remember very well how I appeared.
rather than
I do not remember very well how I appeared.
If you change the initial verb to a synonym, it's correct. I.e.,
No recuerdo muy bien cómo me aparecìa.
becomes
I do not remember very well how I appeared.
I assume it's an error in Google Translate rather than me missing the subtleties of the Spanish language. Yet it seems like such a weird thing to get wrong. I'd really like to get into natural language parsing one day. Maybe then I'd discover the answer.
Labels:
languages
Tuesday, January 17, 2012
Paragliding Tasmania
I and four other paragliding pilots went to the South West Tasmania in December 2011 to fly. On the first day we looked at the Sentinels then flew 12 Trees (5min flight, unfortunately). On the second day we did a couple of good flights off Mt Elisa. We had excellent conditions, mostly blue skies with a little bit of cumulus. Wind was light and nicely flowing up the ridges. Launching was relatively easy. Some of the thermals were strong but the cores were tight and difficult to exploit for beginners.
Flying with Lake Pedder in the background was amazing. Only Klaus (our Austrian import) had a good flight. He flew down to the last ridge then made his way up, above launch, above Mt Elisa, then eventually above Mt Anne. It was really impressive stuff. The rest of us merely delayed our descents. Nevertheless, it was incredibly good fun.
Photos from the trip can be found here.
After the South West, Mark and I tried to fly Winton (the most accessible site out of Hobart). Unfortunately the wind was high and we didn't have the confidence/experience to give it a go. It was good to watch the locals fly the site, however. Hopefully next time we'll get to fly there.
Labels:
Paragliding
Subscribe to:
Posts (Atom)