Tuesday, May 22, 2012

DayZ update

It looks like the developer of DayZ is doing all the right things. Latest update notes:

* This is a pretty major update. I don't really know what affect the new sickness and temperature system will have on player behavior especially with antibiotics being so scarce.
* It is the genesis of an idea, so please remember this might cause havoc. You need to be careful.
* To light a fire, you need matches and wood in your inventory. Place more wood in the inventory of a fireplace to keep the fire going.
* A fire that does not have wood in it will go out when you try to light it.
* You can tell you have an infection, because your character will start coughing. The infection causes you to loose blood down to a minimum of 6000. This leaves you with reduced blood until you take antibiotics.



Here you can clearly see the beginnings of a Minecraft like play. If done right - without the missteps that Minecraft took - could be really good.

How to write software


A friend from my previous job sent me the below a couple of days ago. These suggestions fit perfectly with the exact opposite approach to what we were taking on the project I was working on there. It looks like things are changing.

It's all straight-forward stuff. If you work in enterprise software development, you already know how often these ideas are not followed.



Code Smells Within Classes

·         Comments: There's a fine line between comments that illuminate and comments that obscure. Are the comments necessary? Do they explain "why" and not "what"? Can you refactor the code so the comments aren't required? And remember, you're writing comments for people, not machines.
·         Long Method: All other things being equal, a shorter method is easier to read, easier to understand, and easier to troubleshoot. Refactor long methods into smaller methods if you can.
·         Long Parameter List: The more parameters a method has, the more complex it is. Limit the number of parameters you need in a given method, or use an object to combine the parameters.
·         Duplicated Code: Duplicated code is the bane of software development. Stamp out duplication whenever possible. You should always be on the lookout for more subtle cases of near-duplication, too. Don't Repeat Yourself!
·         Conditional Complexity: Watch out for large conditional logic blocks, particularly blocks that tend to grow larger or change significantly over time. Consider alternative object-oriented approaches such as decorator, strategy, or state.
·         Combinitorial Explosion: You have lots of code that does almost the same thing... but with tiny variations in data or behavior. This can be difficult to refactor-- perhaps using generics or an interpreter?
·         Large Class: Large classes, like long methods, are difficult to read, understand, and troubleshoot. Does the class contain too many responsibilities? Can the large class be restructured or broken into smaller classes?
·         Type Embedded in Name: Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.
·         Uncommunicative Name: Does the name of the method succinctly describe what that method does? Could you read the method's name to another developer and have them explain to you what it does? If not, rename it or rewrite it.
·         Inconsistent Names: Pick a set of standard terminology and stick to it throughout your methods. For example, if you have Open(), you should probably have Close().
·         Dead Code: Ruthlessly delete code that isn't being used. That's why we have source control systems!
·         Speculative Generality: Write code to solve today's problems, and worry about tomorrow's problems when they actually materialize. Everyone loses in the "what if.." school of design. You (Probably) Aren't Gonna Need It.
·         Oddball Solution: There should only be one way of solving the same problem in your code. If you find an oddball solution, it could be a case of poorly duplicated code-- or it could be an argument for the adapter model, if you really need multiple solutions to the same problem.
·         Temporary Field: Watch out for objects that contain a lot of optional or unnecessary fields. If you're passing an object as a parameter to a method, make sure that you're using all of it and not cherry-picking single fields.

Code Smells Between Classes

·         Alternative Classes with Different Interfaces: If two classes are similar on the inside, but different on the outside, perhaps they can be modified to share a common interface.
·         Primitive Obsession: Don't use a gaggle of primitive data type variables as a poor man's substitute for a class. If your data type is sufficiently complex, write a class to represent it.
·         Data Class: Avoid classes that passively store data. Classes should contain data and methods to operate on that data, too.
·         Data Clumps: If you always see the same data hanging around together, maybe it belongs together. Consider rolling the related data up into a larger class.
·         Refused Bequest: If you inherit from a class, but never use any of the inherited functionality, should you really be using inheritance?
·         Inappropriate Intimacy: Watch out for classes that spend too much time together, or classes that interface in inappropriate ways. Classes should know as little as possible about each other.
·         Indecent Exposure: Beware of classes that unnecessarily expose their internals. Aggressively refactor classes to minimize their public surface. You should have a compelling reason for every item you make public. If you don't, hide it.
·         Feature Envy: Methods that make extensive use of another class may belong in another class. Consider moving this method to the class it is so envious of.
·         Lazy Class: Classes should pull their weight. Every additional class increases the complexity of a project. If you have a class that isn't doing enough to pay for itself, can it be collapsed or combined into another class?
·         Message Chains: Watch out for long sequences of method calls or temporary variables to get routine data. Intermediaries are dependencies in disguise.
·         Middle Man: If a class is delegating all its work, why does it exist? Cut out the middleman. Beware classes that are merely wrappers over other classes or existing functionality in the framework.
·         Divergent Change: If, over time, you make changes to a class that touch completely different parts of the class, it may contain too much unrelated functionality. Consider isolating the parts that changed in another class.
·         Shotgun Surgery: If a change in one class requires cascading changes in several related classes, consider refactoring so that the changes are limited to a single class.
·         Parallel Inheritance Hierarchies: Every time you make a subclass of one class, you must also make a subclass of another. Consider folding the hierarchy into a single class.
·         Incomplete Library Class: We need a method that's missing from the library, but we're unwilling or unable to change the library to include the method. The method ends up tacked on to some other class. If you can't modify the library, consider isolating the method.
·         Solution Sprawl: If it takes five classes to do anything useful, you might have solution sprawl. Consider simplifying and consolidating your design.

Monday, May 21, 2012

DayZ, day 2

Totally different experience today. It was daylight. I found a survivor in a few minutes. We worked together to kill zombies and grab loot off dead survivors. (We didn't kill them!)

After taking-down about seven zombies, I ran out of ammo and had to seek safety on top of a pipe, after climbing a ladder. I lost contact with my buddy. I heard shooting and looked up. Off in the distance, there he was again, taking-down zombies from the top of a tower. They went for him, climbing up the tower. Everything went quiet for a couple of minutes. I couldn't move, still too many zombies to try to risk a run for it. But then my new found friend was back again, in a different spot, drawing the zombies away from me. "Run for it!" he cried.

Why did he care? I was useless. Injured, unarmed, stranded in the middle of a zombie ocean. Yet he helped me anyway.

I ran. I got to a higher place. I was safe for now. I read on the server messages that Cal was dead. I was dismayed. How could I have lasted longer than he did? He had all the gear and the knowledge. I was alone again.

A few minutes later I dropped from a platform. My legs were broken. The zombies feasted on my entrails.

Pictures:

Partner in zombie killing

Site-seeing

The zombies

Safe-zone

Zombies climbing

Death

Sunday, May 20, 2012

DayZ

To play DayZ I had to buy Arma 2. After, I followed the installation video-guide on the DayZ download page without a hitch. For mod of a game still in alpha, it was easy to setup.

I started-up DayZ, joined a US server (the Aus and NZ servers were full) and was ready to go.



It was night time. Real night time. No moon. I could hear the waves crashing on the beach and see stars in the sky. I heard ominous music. That was it. It looked like this:


Hmm... What was I to do? I tried waiting for daytime (that's what you do in Minecraft.) It didn't work. After about a minute it was as dark as ever.

I looked in the menu options to find the key to turn-on my torch. There didn't seem to be a key for that. I looked in my kit. I had ten flares. I threw one. I went from no light to so much light that I was clearly a sitting duck. Having read about zombies and bandits, I was concerned. I tried pressing all the keys on the keyboard to find the key that would turn-on my torch. I didn't find the key for "torch." Hmm... That's unusual.

I picked up the flare. I dropped the flare. I picked up the flare. Was I suppose to walk around with a flare in my hand like a complete chump? There didn't seem to be any other option. I couldn't see a thing without a flare.

Off I went, knowing full well that I'd be dead in about thirty seconds time. I crossed a railway line. I found  a derelict building. See Exhibit B, Derelict Building:


I dropped the flare and went inside the house so I could find a bunch of great stuff I could use. Like a torch. The building was empty. The flare went out.

I threw a flare and picked it up to carry with me. I walked away from the building. The terrain changed from flat to a hill slope. I walked up the hill. The flare went out. "Okay," I thought. "I can deal with this. I'll just walk in the dark. I'll be fine."

I walked in the dark. I saw a building. It was the same building as Exhibit B. Unknowingly, I had double-backed on myself.

Perplexion set in. I couldn't walk in the dark. I didn't want to walk with a flare. What was I to do?

I stumbled back to the railway-line. See Exhibit C, Railway-line:


"Okay," I thought. "I'll walk along the railway line." At least I could still see that in the pitch black. After about a minute, I saw a flare! (It wasn't mine!)

I ran to the other flare. I was really excited. I had been wandering around for about 20 minutes with basically nothing happening. Finally, there were people! I was going to say "hello." Sure, they might kill me, but at least I wouldn't die alone.

I was so close. Then I heard a horrible sound. Oh my God, zombies! It was freaking scary. I didn't know where they were but I knew they were close. I fumbled for my pistol. This was going to be nasty. A zombie charged up on me. I fired away. It went down. Then another came up. I missed and it swiped at me. A few more shots though and it went down and all went quiet.

I decided to crouch-down and move slowly towards the flare. That way no-one would hear me. I'd be like a ninja. After all, there might have been more zombies out there and I was still a long way from the flare. I needed to be careful, the second zombie was almost the death of me.

But crouching is slow. After a minute I still felt like I was a million miles away. I decided to make a dash for it. Surely those two zombies were the last. And if not, I could make it to the light before they caught me. I would be like a cheetah.

I was not like a cheetah. I was a wounded and imprudent sucker. Two more zombies heard me and came for me. This time I was too slow. They knocked me prone and started to feast on my entrails. But it wasn't the zombies that really killed me. What really killed me was my impatience and a fool's hope.




My first play of DayZ was confusing, short and ultimately tragic. The only goal I'd had - to reach the flare - was never realised. But I'll be back and I'll have a torch.

2012, the year of the computer game

There are a few good computer games that have come out over the last year, with a bunch more to come. My favourites so far are:

Legend of Grimrock

Such a tight old-school role-playing game. Every component of this game has been thought about. The puzzles, the monsters the characters, the items. There is never enough food. You're always just about to run out of health potions. Monsters are always one step away from killing your characters. You're almost completely lost and confused by the puzzles.

The most freaky moment thus far has been when I was adjusting my character's inventory and an ogre came charging out of the murky black. That was the first time I'd seen an ogre. My party was dead ten seconds later.

There is one aspect to the game that at first seemed tedious. You have to click on a combination of icons every time you want to cast a spell. I eventually realised that this is a way of making the combat more tense. You're trying to remember the combinations and click the icons before you get smashed by something like the guy below.


Unity of Command

As gratifying as Legend of Grimrock has been, every moment of my time with Unity of Command has been better. Thus far, it appears to be a perfectly crafted strategy game. You have to look for weak points in the battle line where you break through with tanks and mechanised infantry to either charge through to an objective or surround the enemy. Supply lines have been implemented so simply but so effectively. It's devastating to see the lines cut by a lone enemy unit.

Unity of Command is like chess where you can beat the computer and feel like such a bad-arse as you do it.

Turn 3. The Russian line has been broken.
Russian units have been cut off from their supply.

Turn 4. German tanks charge through to take the scenario objectives.
German infantry deal with the remaining Russian troops that have been overrun.
DayZ

I played this for the first time a moment ago. Wow. It's something pretty special. I'll write up my feelings about the game in the next post. In short, it's a terrifying game. I have no idea if I like it just yet, but I'll definitely play it more.

DayZ at night. The house is lite by one of my flares.

Games still to come

Two sequels to one of my favourite games are being released this year. They are Xenonauts and X-Com. They look like they're going to be very good.

2012 is shaping up to have very different games to the malaise of mediocre to dreadful games that have been around for long time now. Now all I need is Elite 4 (never going to happen) or a new X-Wing game to come out and I'll be set.

Saturday, May 19, 2012

Diablo 3

I'm playing Diablo 3 multi-player this evening. It is the first time I've played a Diablo game multi-player. I have fond memories of the original Diablo game from 1997. I played it for hours, though never got close to finishing it. I never played Diablo 2.

I've played Diablo 3 single-player this week. I find it utterly perplexing. There are some astonishing design decisions. They seem so poor and obvious that I realise they can be nothing but deliberate. These are:
  • Gold is something you need to pick-up, rather than being instantly added to your inventory. Why oh why?
  • There are really special magic items need to be identified before they can be used. This takes a right-click and about 10 seconds. WHAT is the function of this mechanic?! I am completely baffled by this.
  • The story seems neither good nor bad but completely antithetical to the sort of game that Diablo 3 attempts to be. In multi-player, especially, I can't see how the story could do anything but get in the way.
  • Health orbs drop at such a rate that they are frustratingly difficult to avoid as they work instantly and don't do anything if you're already at full-health. It's as though I'm being punished for not being very good at evading a good thing (that I might have wanted to come back to later).
  • Every attack is a special attack. I was completely thrown by this. How do I make a normal attack? You don't. It probably didn't help that I started with a Monk and therefore assumed that he wouldn't be using any weapons at all.
  • Aside from the big fat men that explode snakes, none of the monsters have been particularly interesting. I was expecting a lot of funky variations. Maybe they come later. Maybe.
Add to this list issues with lag and DRM. Yet, Diablo 3 isn't a terrible game. I'm not sure that it is fun, but it's compelling enough.

Almost all of the issues and weirdness can be blamed on D&D. Designers need to get beyond D&D. Game rules for RPGs are basically arbitrary. You can come up with whatever you want. D&D had a whole bunch of really dumb stuff that was baffling when played around a table and completely useless when played on a computer. RPGs, computer or otherwise, need to get away from D&D almost completely.

Monday, April 30, 2012

Windows Phone 7 apps


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

Tuesday, March 20, 2012

Comments on Windows Phone

I bought a Nokia Lumia 710 yesterday, my first smart-phone. I've tried the iPhone quite a bit and have an iPad. I've had a play with some Android phones. Somehow Microsoft have managed to make the best mobile OS out there.

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.
Things I don't like:
  • 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)
I'm glad I bought a Windows Phone over an iPhone or an Android phone. The integration is great. I really dislike the app hell (too many apps all over the place!) I get with Apple. The design is much better too. I still shudder when I bring up Notes on the iPad. Ick! But WP is still playing catch-up with Google and Apple. I want the future Apollo features today. Just imagine what people will be able to do with app to app communication.

Thursday, March 8, 2012

Computer Reversi, Part 1.5: The Thor database (Othello tournament files)

As part of my research into Reversi, I looked for an archive of games. The only substantial one I found is called the Thor Database. It's an archive of Othello games by French archivers. They have archived are over 100,000 games. You can download the game databases here.

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).)
To calculate the Black Score:
  • 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;
E.g., Black has 44 pieces, White has 8 pieces; Black's score is 56. Or, Black has 13 pieces, White has 35; Black's score is 13. In the case of a draw, Black's score is 32 (as the empty squares are shared between Black and White, 32 is the only possible score for a draw). I still haven't figured out what it means for Black's score when the game ends before neither player can play a piece. The score seems inconsistent. This only occurs in 406 of 107,473 games. (Not a big deal.)



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)
Game fields
  • Tournament Number
  • Number of Black player
  • Number of White player
  • Number of black pieces (true score)
  • Theoretical score
  • Move list 
The plays are stored in chronological order. Row number (1-8) and column (A-H) can be derived from the following operation: column + (10 * row). E.g., a1 = 11, h1 = 18, a8 = 81, h8 = 88.

Tournament file
Each record (26 bytes) is an array of characters terminated by a binary zero. The effective length is 25 characters. There is a 16 byte header for this 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.

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
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.

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
  1. Game state representation
  2. Move generation
  3. Move resolution
  4. Determine game over and winner
  5. Graphic User Interface
  6. Save/load and undo/redo moves
  7. Position evaluation (i.e., fitness/objective function)
  8. Depth-first search algorithm (e.g., mini-max or nega-scout)
  9. Book/database based analysis (e.g., opening book, transposition tables) 
  10. Mathematical optimisation (e.g., simulated annealing or genetic algorithm)
This blog entry addresses steps 1-6, providing source code for a Unity implementation of Othello. The game logic is written as C# and compiles as mono inside Unity. I assume knowledge of:
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
There are source files, 64-bit Windows binaries and Mac OSX binaries. There are two solutions files contained in the source files. The one named with VS2010 is the one you should open in Visual Studio. It contains a test project and a preliminary attempt at reading the Thor database format. But that will be for another post. You can load the project in Unity via the "Reversi.unity" in the Assets sub-folder.

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
GameState

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.
Part 2

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.

Friday, January 20, 2012

Google Translate

Google Translate works quite well. Occasionally it does some weird things. For instance, it translates (from Spanish)

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.

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.

Sunday, December 18, 2011

Editing IE settings in the registry via C#

We have a weird setup at work where our Internet Explorer LAN configuration settings are periodically reset by people who manage the network. This brings IE and TFS to a crawl for the programmers. It doesn't seem to happen to everyone all at once or at a designated time. It can take a few minutes to realise what is going on as there are a number of issues that show similar behaviour. For new programmers, this is especially frustrating because they're not aware of this strange policy.

To the Windows registry Batman! I haven't played with this thing in years. I never really understood it very well. "Hierarchical database? All these weird names? Huh? What's going on?!" Seems so simple now.

Editing the registry in the .NET environment is easy. See here.
Finding how to change LAN proxy configuration settings took a little longer to find. Explained here.
Proxy exceptions? See here.

With the app working, all that is left to do is set the script to run every 15mins on the programmers' computers, and we're done.

Code looks like:

var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"true);
 
if (key == null)
  throw new NullReferenceException("Registry SubKey not found.");
 
const string defaultConnectionSettings = "DefaultConnectionSettings";
var defaultConnectionSettingsValue = (byte[])key.GetValue(defaultConnectionSettings);
 
defaultConnectionSettingsValue[8] = 1;
key.SetValue(defaultConnectionSettings, defaultConnectionSettingsValue, RegistryValueKind.Binary);

Friday, December 16, 2011

Code generation in C#

I wrote my first code generator on the weekend. The real work - generating the C# class files - was trivial. Getting the generator into a state so that it could be easily used was more difficult.

There are a few ways you could do code generation in .NET. I explored:
I went with T4 Templates. They were a little obscure at first but provided the easiest entry point into using the code generator. You just build-up your source file and then right-click and select "Run Custom Tool" on the .tt file to generate the code.

I encounted a few issues when trying to write my template. They were:
  • Extension methods can't be embedded into a T4 Template. There is a workaround. I ended up converting my extension methods into normal methods (I only had two).
  • Accessing your assemblies is difficult in Visual Studio 2010. It has been explained very well. I managed to access my assemblies by writing something like <#@ assembly name="$(SolutionDir)..\DomainEntities\bin\Debug\Cpa.DomainEntities.dll" #>
The example T4 Templates I found on the Internet were a little more complex than what I wanted. (Examples should be as simple as possible.) I wanted to load a source file into memory and generate class files from that. Download my example template if you want something similar. It loads in a CSV file that has two columns (first column is the name of the class, second column the name of the property) and generates some puesdo-code of what the class files will eventually look like. I used this as my base template, then expanded it to create proper C# class files.




Tuesday, November 22, 2011

Comments on Skyrim


I've been playing Skyrim in my (ever dwindling) spare time.

Good things:
  • I play by simply allowing myself to be drawn to whatever seems interesting. I don't particularly care about completing quests, I wander. It's working really well for me. I'm often stumbling onto something interesting.
  • I went on a quest to recover a helmet. (I deliberately chose the most banal of the quests.) It was fun. I crossed over a bridge in a treacherous cavern. I fought a couple of frost trolls. Burnt 'em.
  • I started back to Solitude (a city of Skyrim) and saw the ghost of a headless horseman ride by. It just appeared and rode off. I tried to follow it for a while but was distracted by some midnight revellers who offered me a drink. I drank. When I looked back, the horseman was gone.
  • I saw some rabbits hopping around underwater. Then I saw a white wolf walking underwater. Mammals in Skyrim have strong lungs.
  • On the quest to "find King Olaf's verse," I made my way to the body of Svaknir, at the bottom of a stairway. I was expecting to find a book here. There was no book. My character became trapped in a dungeon, never to escape. (Some bugs are cool.)
Bad things:
  • Books in Skyrim are boring. Tip for next time: Bethesda, if you're going to have poorly written text, write less of it and link it to the gameworld in some way. I only open books because of the possible quests or skill bonuses.
  • Food appears to be useless. They've put so much effort into it, it would have been good to have a requirement where you need to eat and drink occasionally to keep your stamina up.
  • The UI is bad. You can use it and thankfully the core of it (choosing spells and items) is okay, but it's still bad. You have to hit 'tab' to close the menu? What's wrong with 'esc'? See: interface comments.
Skyrim screenshots

Wednesday, November 9, 2011

Occupy Melbourne

I went to my first Occupy Melbourne general assembly this evening (the 16th they've had). It wasn't deliberate, I was walking on Swanston St, eating my chips & tomato sauce, and there they were. I stayed for a couple of hours. My impressions follow.

I'm not very good with numbers, maybe there were 100 people. They used the (predominate) megaphone and the human microphone. Decisions were run on a consensus basis.

It was very much a left ghetto event. However, it was as though the factions had set their differences aside for participation in Occupy Melbourne.

The first hour was reports from various workgroups (legal, direct action, media, etc.) on what they’d been doing since the last GA. The legal team were going to court over whether Occupy Melbourne could have structures and political posters at Treasury Gardens. They wanted people to await the outcome of legal proceedings before Occupy Melbourne decided to do anything more.

I was disinterested by the first hour. If I were a part of Occupy Melbourne, maybe I’d have been more interested (but probably not).

After the reports there were some more substantial suggestions. The first motion was that Occupy Melbourne has a minute silence for the dead of WWI. I was shocked. I had thought that nothing so conservative would ever dare to be tabled. A show of hands for, then against. There was massive dissent. It was quickly reformulated as "all that have died in all wars". There was massive dissent. Others spoke against war per se. They didn’t want to honour victims, they wanted to attack the perpetrators of war, the 1%. I was encouraged by this, but by then, 10-20min of my life had already disappeared before the motion was thrown out. (I definitely would have walked away forever if it had been accepted in any of its forms.)

After, there was a proposal that we build structures on Saturday, regardless of the legal outcome. There was general (60-70%) support for this. One dissenter made an absurd analogy to guerrilla tactics saying "now is not the time to attack but harry the enemy." This received quite a bit of support. One commenter riposte with "This isn't the Vietnam war." Another dissenter talked of not wanting to jeopardise legal proceedings (the interim outcome, everyone already knew, would be known before Saturday). This rhetorical nonsense (clearly suffering for causal misdirection), received even more support than the guerrilla fighter. However, speakers for or against were unable to sway the numbers significantly. (I voted for occupation with structures, too horrified by the nonsense of the dissenters to abstain any longer.) It was decided to revisit the issue on Saturday. After that, I left.

I was generally quite impressed. For all my critical thoughts, it seemed like a movement with promise. Are the "Occupys" around the world the beginnings of a 21st century soviet? I don't know. I don't think anyone could know that. They probably aren't though. They'll probably fizzle and burn out. To avoid that fait, they need to inspire people to take control of their lives. I have no idea how they're going to do that. Hundreds of years of failure gnaws at the edges of the general assembly.

Friday, October 7, 2011

Steve Jobs once said

"Live every day as though it were your last." Absolutely, do not do this. You will be wrong for every day except for one.

Wednesday, September 14, 2011

Some funny code...

I often sigh while reading the source code at me new job. Occasionally, I have a few laughs too. For example:

            catch (Exception exception)
            {
                throw new Exception(exception.ToString());
            }


I'm not sure what it is about exception handling but it seems to be the most frequently mis-understood/mis-used area of programming C#. The lines above are not nearly has bad as:

            catch (Exception exception)
            {
            }

which I've seen a lot of too, but it's more of a sigh moment than laugh.