Monday, October 5

Pencil and Paper Strategic Sea Battles Game

It was school holidays, and I wanted to spend some quality time with my daughters. I remembered how much fun I used to have playing Pencil and Paper Sea Battles Game with my brothers when we were kids. So, I went online to find a version of the game we used to play—but none of what I found matched my memories.

So I recreated the game from scratch, based on how we played it all those years ago. I put together a few game sheets, and to my delight, they were a big hit with my daughters.

To this day, I’m not sure whether my brothers and I invented these rules ourselves or adapted them from somewhere else. If any kind reader recognizes this version or knows where it might have originated, I’d love to hear from you.


Burns Family Rules for Sea Battles

Each player uses a game sheet with a grid labeled “Your Ships” and a corresponding “Opponent’s Ships” grid.

Unit Placement

Players begin by placing the following battle units on their “Your Ships” grid:

  • Units can be rotated or flipped in any direction.
  • Units must not be placed diagonally.
  • There must be at least a one-square gap between all units—orthogonally and diagonally.

There are three types of units, each with placement rules:

These ships must be placed in ocean squares on the grid.

These air units can be placed on any squares on the grid.

These ground units must be placed on land squares on the grid.


Refer to the unit tally boxes on each particular map to see how many of each to place. Tick them off as you go.

Taking Turns

Once all units are placed, players take turns firing shots to locate and destroy the opponent’s units.

Standard Attack:
  • Announce a grid location (e.g., “B4”).
  • Your opponent replies with:
    • “Miss” – if there’s nothing there.
    • “Hit” – if part of a unit is located at that square.
  • Mark your “Opponent’s Ships” grid with:
    • A slash ( / ) for a miss.
    • A cross ( X ) for a hit.
  • When all squares of a unit are hit, your opponent must announce the unit’s name (e.g., “Cruiser destroyed”). Cross it off in the tally box.
Mega Bomb (Special Move):
  • Announce a target square.
  • The bomb hits that square plus all eight adjacent squares (the surrounding 3x3 area).
  • Your opponent announces:
    • Any hits, along with their locations.
    • Names of any destroyed units.
  • Record the use of a mega bomb by marking an ‘M’ in the tally box.

    Winning the Game:

    The first player to destroy all of their opponent’s units wins. names of any ‘Ships’ destroyed. Cross out an ‘M’ tally box each time you use a bomb.


    Update :

    I keep getting feedback that people want quicker games so  I added some more small maps and re-did the letter code sizes. 


    Jagged Coast SS
      The maps go from small small to extra large 

    Jagged Coast XL


    Update 2 : 

    I added a interactive game down the bottom so people could try out the different maps.


    Game Sheets


    Demo  of Maps

    Geoff's Hidden Battle

    Seek Mode

    Enemy Waters

    Click On Square To Fire
    Single Shot Mode

    Tally Boxes

    Shots: 0
    Hits: 0
    Sunk: 0 / 8

    Thursday, October 1

    Source Code on Github for Simple Card Game written in Swift


    I knocked up a simple game in swift using SpriteKit as part of a job interview. Its based on a game my family plays all the time using real physical cards. I put it in the app store under the name Rickety Kate and uploaded the source to Github. You might find it takes 8 to 16 days for the code in the repository to find its way to the app in the App Store, one and half review cycles on average.




    I probably over engineered this one. You can build your own deck of cards, anything from a 40 card deck with 4 suites to a 168 card deck with 10 suites. I knocked up some very simple input controls to control the options.




    Putting 1x and 2x images  in texture atlases was a little finicky. I did a little experimentation and the 2 versions of the images seem to need to be in the same atlas for the 2x images to be automatically used in a retina device. Also here were problems unless all images in a atlas had the same number of versions e.g. they all needed to have 2x versions or none should have them. I have not tried using 3x images yet.

    I am going put out a series of very simple games and apps. I put out another card game called Sevens. Next one after that is going to be a tilt game with retro neon line graphics. Set in the wreckage of a large city post alien invasion, you pilot spacecraft picking up refugees, and ferrying soldiers, diplomats, wounded, equipment and supplies while avoiding Lurkers, Tripods and Space Jellyfish.


    Update: Rickety Kate 1.1.4 Just passed review (22/01/2016) and  v1.0.2 just passed review (09/01/2016)

    Rickety Kate is now localised for English, French, German, Portuguese and Spanish.

    Wednesday, September 30

    Is it worth while transitioning from Objective C to Swift?

    I 'm late to this bandwagon. However I had a heavy investment in an Objective C code base and a lot of distractions. Enough with the excuses, better late than never.

    I know others have held off for many of the same reasons I did. So the question is useful. Was transitioning to swift worth it? The answer is a definite yes.

    The Pros

    No pointers and no nil-able values or objects unless they are wrapped in an option. This cuts down on a large class of errors.

    Named parameters. This language is targeted for Objective C programmers so of course it has name parameters, however I still count it as a plus because named parameters increase readability and are a good idea, even C# has named parameters theses days.

    No lisp-like nested square brackets everywhere (yes I know lisp uses round brackets, however I am talking about the nesting behaviour)

    Immutable values using the let keyword. This reminds me of Scala's val and var keywords and of F#'s let keyword, although F# makes it harder to make values and objects mutable. Immutable values can make an application easier to reason about and make it easier to do concurrent programming (less need for locking)

    No more header files.

    Memory management that doesn't feel like a tacked on after thought .

    Only one form of closure instead of the two different flavours in Objective C (selectors and blocks)

    The 'if let' statements ability to chain together multiple let statements capped with a where cause reduces nesting and as nesting plays havoc with readability this is all to the good. There is a 'if var' version but I never see it used.

    Swift has its own REPL which in Swift's case is called a playground. REPLs are common in many interpreted languages, they are ideal for learning and experimentation. REPL is pronounced 'reppel' and stands for Read Evaluate Print Loop and at its heart in a very simple, effective and old piece of technology.

    No more need to box and unbox value types just to use collections. I remember when C# had this problem (versions 1.0 and 1.1 fixed in 2.0), but at least C# 1.1 had the __box and __unbox keywords,  in Objective-C you have to wrap and unwrap value types by hand.

    Swift has generics, type safety and even type inference. Plugging that hole (lack of generics) in the type system pays off massive benefits in reduction of errors and increased ease of use. There is no way to have general purposes containers like lists and dictionaries without either having a generic type system, using dynamic types or breaking the type system by casting away type.

    Less use of special characters in syntax, no more semi-colons at the end of your lines and a more modern cleaner looking syntax.

    Initial Annoyances / Gotchas

    You will need to lose the habit of surrounding if conditions with brackets as this can break things. This is initially is frustrating, but when you get used to it, it actually looks cleaner.

    Significant white space between operators and operands or lack there of will turn binary operators into prefix unary operators.

    Xcode habit of warning you that you have not used a declared variable or constant straight after you have declared it and before you have had the chance to type the line that will use it, can initially be distracting.

    The Cons

    I am used to uninformative and obscure error messages, but Xcode has reached a new low in this lost art of sowing confusion. After a while you get an idea about what it could be complaining about, but even when you know what is causing the problem, drawing a meaningful relationship between the error message and the cause of the problem can be bewildering.

    The navigation and intellisense  tends to break when you need them most.

    No refactoring support for swift yet compared to Xcode refactoring support for its other supported languages, not that Xcode Objective-C refactoring support is terribly good, but at least its there.

    Lost Opportunities

    There is a lot I could say about this, but Objective-C does worse in features I want to complain about so I will just point you to a post that Rob Napier wrote about how swift is not functional and save the rant I was going to write here for another blog post.

    The Experience

    The first one or two weeks was frustrating. Most of the frustration was centred around the compiler. However the learning curve was surprisingly easy. After two weeks I felt more comfortable with Swift than Objective-C even though I have been using Objective-C for years. Their is very little in Swift that isn't a standard expected feature in a modern programming language. Even the syntax and the keywords are pretty stock standard. Given the blandness of Swift the main reason for its existence is obviously to have built-in compatibility with the existing libraries and APIs and to make migration from Objective-C and interoperability with Objective-C easy. In achieving these goals Swift is successful.

    Conclusion

    I am not going to rewrite all my Objective-C code base in Swift. However all new work is going to be in Swift and even major modifications to old projects will probably be in Swift as you can mix the two languages in the same project.




    Tuesday, September 29

    The Secret to Managing Images, Sounds and other Resources for Mobile Apps

    Managing Images, Sounds and other Resources
    F

    our Simple Rules for Managing Assets

    1. Automate, Automate, Automate
    2. Keep all the source artefacts and scripts needed to produce the final resources under source control e.g git or mercurial (don't bother with the derived images)
    3. Give everything long descriptive names and a systematic logical folder hierarchy.
    4. Use texture atlases rather than individual images ( originally I used Zwoptex to generate texture atlases for me, but now days Xcode does it automatically for me ).

    Why It Matters

    When you first start adding images and sounds to your app it doesn't seem like a big deal to do things manually. Any half baked semi-functional  process or algorithm works as long as 'n' is small. But as the number of images and sound clips grow you will pay a higher and higher price for poor decisions you made at the start. It does not take long before you have hundreds of images and sounds. Any technique that allows you to cut down the number of images is a technique you should use. A favourite trick of of mine is to split an image into several layers and to tint one or more layers programatically to get several different colour themed images.


    The Resolution Problem

    Images tend to “breed like rabbits” because of the many device resolutions and aspect ratios we must support. Manually creating separate images for each device is a fast track to burnout.

    Here are two strategies I use to stay sane:


    Solution 1: Downsample High-Resolution Images

    Make your images at the highest resolution and then down sample to get your lower resolution. One of my favourite tools to do this is ImageMagick as it has a command line interface and therefore can be called from a script. You can use it to resize, crop and rotate images plus much, much more. 

    If I am using a Mac prefer to use the MacPorts package manager to install apps like this, if I am using Windows I use the Chocolatey package manager.

    Once you have a package manager  you type in the following into the terminal for the mac
    sudo port install ImageMagick
    or the following into the command window for Windows
    choco install imagemagick.app
    Nicholas Waynik has a tutorial on how to use the resulting images on the iPhone and iPad.

    Solution 2: Use Vector Formats (e.g., SVG)

    SVGs let you rasterize to any resolution as needed. I prefer this approach—especially when I revisit and modify assets for animation or reuse.

    I tend to use this solution as I have the habit of going back and spitting my old images into parts in order to animate or reuse the image in someway. It is easier to modify a vector image later if you have to. Inkscape is a good drawing app to use for creating the images.

    It does have a command line interface but you have make it jumps though hoops if you want to make it rasterize an entire folder of vector images. Which is exactly what I am always going to ask it to do. You do not want to create the final rasterized (e.g. *.png) images this manually though the GUI. Remember rule number 1. I use the following snippet in the bash scripts I use to generate the final images.

    for i in /full-directory-path/*.svg; do /Applications/Inkscape.app/Contents/Resources/bin/inkscape $i -w 100 -h  200 --export-png=`echo $i | sed -e 's/svg$/png/'`; done

    and for the 2x images

    for i in /full-directory-path/*.svg; do /Applications/Inkscape.app/Contents/Resources/bin/inkscape $i -w 200 -h  400 --export-png=`echo $i | sed -e 's/.svg$/@2x.png/'`; done

    You can either copy and paste these command into a mac terminal window or place them in a text file with a *.command extension to create a clickable command.

    I modified the this script based on a piece of bash script voodoo I got from gastarbeiten who in turn got it from someone called forger. The original script no longer works because the upgrade to inkscape 0.91 broke it, thankfully it only took a minor tweak to get it working again. Fair warning these scripts sometimes need little care and feeding every now and again. I seem to need to fix them about once every 6 months. Despite the very occasional annoyance these scripts are a life saver.

    What About Batik?

    I used to rely on Batik for SVG rasterization. It supported batch processing out of the box, no scripting required. But a Java update broke it, and the blame game started. Maybe it’s been fixed by now—but I’ve moved on.

     

    Final Thoughts

    As your app grows, automation and forethought are the only scalable options. Don’t wait until you’re drowning in assets. Build a pipeline early. Script everything. Version everything. And treat asset generation as code.

    Your future self will thank you.


    Related Posts