20180618

Post Scriptum Mortar Calculator


If you find the app helpful, I and my cat would appreciate any support you could send our way.


App is released for free, with no annoying ads and will ask for no permissions. I hope you will all appreciate this. Any gifts will keep a thirsty developer in some beer - and recoup the 25USD for the Android Developer Account. Also it will go to keeping the cat distracted by Tuna bribes in order to stay off my keyboard...

(The surrender tuna or keyboard look...)

VERSIONS:

Version format: [major release].[new feature(s)].[bugfix patch-version] 
0.0.9: Public beta test version
1.0.0: First Release
- Fixed divide by zero bug crashing the app 
- Added Mils calculation 
- Added current mortar models and selection between them 
- Added About button linking to blog with instructions 
1.1.0: Second Release
- Added minimum range for the various mortars 
1.2.0: The Yanks are coming!
- Added US 4.2" Mortar 
1.2.1: Simplifying it
- Ripped out the 4th coordinate as it confused quite a few people 
- Changed Android API version to comply with latest requirements from Google Play
1.3.0: Le Baguette
- Added French mortars
- Fixed a slight issue where on some aspect-ratios, button-text could go outside the button boundary

USAGE:

Enter in coordinates for Mortar and Target position using the keypad. For the first coordinate, hitting the key once, twice or thrice will change between the letters printed on the key. You know, like the good old times writing SMS messages on our phones. When done, hit the '>>' key on the keypad.

The second coordinate can be either a single or double digit number. For a single digit number, hit the selected number you want, and then hit the '>>' key. For double digit, first enter in one number and then the other before hitting the '>>' key. Couldn't be simpler.

The next two coordinates are single digit only. Change between them using the '>>' (next) or '<<' (previous) keys. You get these from the in-game map.

To change between entering mortar coordinates and target coordinates, hit either the 'MRT' or 'TGT' button.

When satisfied, hit the 'Calc' button. To change between coordinates, use '<<' and '>>' on the keypad. To change Mortar model (important for correct mils calculation), hit the '<<' and '>>' buttons on the upper row above the display. Changing mortar will automatically recalculate the mils value.

The 'About' button will take you to this screen.

FUTURE:

Next version will be released to coincide with the 'Post Scriptum Big Update!' that should feature a new faction - and thus at least one new mortar.

FAQ:

Q: Why not an iOS version?
A: Hey, buy me a Mac, an iOS device and 100USD to cover the (yearly) Apple Developer subscription, and I can push out a version for iOS in less than a day!

Q: What was used to develop this App?
A: App Game Kit 2 by The Game Developers. It's basically a language and C++ library to facilitate more or less pain-free cross-platform 2D and 3D app development. No 'code-by-menu-hunting' approach as in Unity, but good old writing code into an IDE and compile/export.

Also GIMP for creating the graphical assets, and Audacity to edit the little clicky sound.

Q: Is it Open Source?
A: Yes - and no. The code I've written for this app is under MIT License. However the underlying App Game Kit framework and runtime is proprietary and owned by The Game Creators Ltd.

My code for this app is available at https://github.com/rDybing/PS_RangeBearing

Do note that any graphical assets are not included in that repo.

20180525

Changing values in a slice in a struct in a map...

Maps in Go are great as a out of the box simple key-value datastructure. However, maps can be a bit rigid from time to time. For instance, adding new instances into a slice in a struct in a map reference had me scratching my head quite severly.

So I made a little demo-project to work out the procedure. This is a bit clunky I must admit, but it do work.

---
package main

import (
    "crypto/sha1"
    "fmt"
    "hash"
    "io"
    "math/rand"
    "time"
)

type myStructT struct {
    name string
    pets []string
}

func main() {
    var myMap map[string]myStructT
    myMap = make(map[string]myStructT)

    rand.Seed(time.Now().UTC().UnixNano())
    mySlice := initSlice()
    myMap = initMap(mySlice)
    printMap(myMap)
    myMap = editMap(myMap, "Dewey")
    fmt.Println("----- After edit -----")
    printMap(myMap)
}

func editMap(in map[string]myStructT, index string) map[string]myStructT {
    var h hash.Hash
    var hash string
    var old myStructT

    h = sha1.New()
    io.WriteString(h, index)
    hash = fmt.Sprintf("%x", h.Sum(nil))

    old = in[hash]
    delete(in, hash)
    old.pets = append(old.pets, "Alligator")
    in[hash] = old
    return in
}

func printMap(in map[string]myStructT) {
    for i := range in {
        fmt.Printf("Name: %s\n", in[i].name)
        if len(in[i].pets) > 0 {
            fmt.Printf("Pets: %d\n", len(in[i].pets))
            for j := range in[i].pets {
                fmt.Printf("- %s\n", in[i].pets[j])
            }
        } else {
            fmt.Println("No Pets :(")
        }
        fmt.Println("----------")
    }
}

func initSlice() []myStructT {
    var s myStructT
    var out []myStructT

    name := [3]string{"Huey", "Luie", "Dewey"}
    pets := [6]string{"Cat", "Dog", "Ferret", "Bunny", "Hamster", "Parrot"}

    for i := range name {
        s.name = name[i]
        s.pets = nil
        x := randInt(0, 3)
        for j := 0; j < x; j++ {
            y := randInt(0, 6)
            s.pets = append(s.pets, pets[y])
        }
        out = append(out, s)
    }
    return out
}

func initMap(in []myStructT) map[string]myStructT {
    var h hash.Hash
    var hash string
    var s myStructT

    out := make(map[string]myStructT)

    for i := range in {
        h = sha1.New()
        io.WriteString(h, in[i].name)
        hash = fmt.Sprintf("%x", h.Sum(nil))
        s = in[i]
        out[hash] = s
    }
    return out
}

func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

---

Essentially what happens is that I import the map, copy the given index I want to modify into a temp struct. Modify the temp struct as per usual procedure. Then kill the map instance of the given index, add a new map instance using the same index, and fill it with the modified content of the temp struct.

Finally, return to sender.

Hopefully I can find a better solution, I think I've read something about using pointers to operate directly on the map struct.

If I got it right, the map will then only contain a pointer to a given struct and it's instance. I'll have to read some more, ask around and lubricate my brain with beer to get there though...

20170708

Plugging TLS into your Go Backend - for free!

I don't think I need sell anyone on the concept that securing client-server traffic is a good idea. These days we can even do it for free through Let's Encrypt.

In my example of how to implement it, I'll assume running an Ubuntu server. First order of business is getting Let's Encrypts' Certificate Generator up and running on your system, cutely named Certbot. This will create your TLS certificate, and later update it.

The one downside of using Let's Encrypt is that the certificates only last 3 months before needing to be re-issued. If you're clever, you'll have your backend do it automatically by either generating new ones on each deploy (assuming reasonably high frequency of updates) and/or during daily Cron jobs, check the timestamp of the certificate files, and renew if getting close to the expiration date.

Another gotcha is that Let's Encrypt won't issue certificates to typical AWS domain names like <ec2-12-123-12-123.eu-central-1.compute.amazonaws.com> as these servers can easily be used for various nefarious purposes. So you're going to need a proper address to plug into your certificate. Any DNS service will let you point to your AWS EC2 instance, so it's no biggie. If you already got one, say for a website, just set up a subdomain there that points to your AWS IP.

I'll not go into those topics in any detail here though. So moving on, the very first thing on the agenda, is installing Certbot and generating the certificates.

Once you've SSH'ed into your server, this will get you the bot:

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot


Next, since we're not running some external webserver or anything like that, but let the goodness of Go do it for us, we'll need a 'standalone webserver' certificate that we can use.

$ sudo certbot certonly --standalone -d katzrule.com -d www.katzrule.com

This will create the two files you need import into your Go app. You'll find them under '/etc/letsencrypt/live/katzrule.com/' and they should be named 'fullchain.pem' and 'privkey.pem'.

How you import them into Go is a matter of preference. I'm a bit lazy, so I didn't want to comment in and out the loading of the certs for when developing (just testing using localhost) and when deploying (running live on AWS). So I set up a little type to hold the location of the certs, made a function to test for if I am on live server or not, import the certificate location into the previous made type if on the server, and then finally in the API function, serve up over https or http depending on if certificates are found or not.

So the implementation itself.

In package structs:

type TLS_t struct {
    Fullchain string
    PrivKey   string
}


In package fileIO:

func GetTLSExists() (structs.TLS_t, bool) {

    var fullchain = "/etc/letsencrypt/live/katzrule.com/fullchain.pem"
    var privKey = "/etc/letsencrypt/live/katzrule.com/privkey.pem"

    var TLS structs.TLS_t
    var exists bool

    if _, err := os.Stat("./conf/app.ini"); err != nil {
        exists = false
    } else {
        exists = true
        TLS.Fullchain = fullchain
        TLS.PrivKey = privKey
    }
    return TLS, exists
}


The file I check for - './conf/app.ini' only exist on my server. You can check for any file you wish that you know only exist on the server - or have an initialization file you load on startup, with one field (assuming JSON or XML encoding) saying if on live or dev. Anyway, this little hack works for me.

Finally in my API package:

func Initialize() {

    router := mux.NewRouter()

    ip, err := fileIO.GetPrivateIP()
    if err != nil {
        fmt.Println("Error loading IP config - exiting")
        postgres.Close()
        os.Exit(0)
    }

    server := &http.Server{
        Handler:      router,
        Addr:         ip,
        WriteTimeout: 10 * time.Second,
        ReadTimeout:  10 * time.Second,
    }

    router.HandleFunc("/noDogParkPetition", noDogPark)

    TLS, live := fileIO.GetTSLExists()
    if live {
        fmt.Println("TLS Certs loaded - running over https")
        log.Fatal(server.ListenAndServeTLS(TLS.Fullchain, TLS.PrivKey))
    } else {
        fmt.Println("No TLS Certs - running over http")
        log.Fatal(server.ListenAndServe())
    }
}


And that is about it. Those with keen eyes may notice my call to fileIO.GetPrivateIP() - this is merely a call to load the IP address. For the same reason as mentioned earlier. By loading the IP from file rather than hardcode it, I can move the app freely between dev and live by just uploading the updated binary. On dev, the file just tells the app to serve on localhost, on live it loads up my AWS outward pointing IP and port.

Makes deployment super easy. SSH in, close down the app (and do the usual linux/Ubuntu update/upgrade since this is a very good time to do so), use Filezilla to FTP over SSH the new binary, then start it up all good to Go - if you pardon the pun.

Happy - and secure - coding! :)

20170621

Bounce buttons in Array

This post is derivative of the one I did in this reddit thread. There though the focus was more on how the OP could restructure his code to not only make it work, but also get rid of multiple repetitions of basically the same code.

Anyhow, making the little example to get him on the right track, I stumbled upon another little challenge. Anyone who's been doing any Arduino projects for a while most likely have gotten to use the <Bounce2.h> library.

For those who have not, the short of it is that it relieves you of the task of debouncing buttons manually in code - or for that matter in electronics by routing the input through a schmitt-trigger chip.

Just attach buttons in software to the Bounce object, and you're good to go. Which is fine when you got one to three buttons all assigned their own unique ID. Any more, and it soon looks both tedious and newbish to declare a ton of buttons like so:

Bounce buttonA = Bounce();
Bounce buttonB = Bounce();
Bounce buttonC = Bounce();


Which also bring on the issue of each little 'is a button pressed?' routine need be in triplicate - one for each unique button. Surely stuffing all that stuff into an array is much better?!

Which I set out to do in my little example of 'clean & structured' code. A little research and trial and error later, this is what I came up with:

#include <Bounce2.h>

const byte ledPin[2] = {10, 11};
const byte butPin[2] = {2, 3};

Bounce button[2] = {
  Bounce(butPin[0], 2),
  Bounce(butPin[1], 2)
};

bool ledState[2] = {false, false};

void setup(){
  for(byte i = 0; i < 2; i++){
    pinMode(ledPin[i], OUTPUT);
    pinMode(butPin[i], INPUT_PULLUP);
    button[i].attach(butPin[i]);
  }
}

void loop(){
  for(byte i = 0; i < 2; i++){
    if(getButton(i)){
      flipLED(i);
    }
  }
}

bool getButton(byte b){ 
  if(button[b].update() && button[b].read() == LOW){   
    return true;
  } else {
    return false;
  }
}

void flipLED(byte b){
  ledState[b] = !ledState[b];
  digitalWrite(ledPin[b], ledState[b]);
}


The only surprise, and what had me scratching my head a bit, is that each declaration of a Bounce object, need have the max number of objects at the end - after the pin assignment of it.

Another little thing to note that beginners may not realize, is that 0 = false = LOW, and conversely 1 = true = HIGH. So rather than turn the LED on and off through your typical if(this){do that} routine one can save oneself a bit of work and CPU cycles by making the led state variable a bool - essentially a bit - that you can flip easily with the not '!' operator.

Doing proper bitwise operations would be more efficient - but this example was to help a beginner. No need to confuse more than strictly speaking necessary :)

20170521

rPi 3 vs Parallella benchmark

Been knee deep in C# lately, so updates have been rather sparse. Well, non existent really. Anyhow - got the desire to have a little fun with my Pi3 and another favourite of mine, Go.

Basic premise; see how faster a bit of Go routines would make a simple program. Copy - Paste from the reddit thread I made for this project:

---

First, I do not have a Parallella - so I'm using the numbers from this talk:

Parallella Demonstration

The gist of it is, it got 2 ARM cores and 16 custom RISC cores - and testing it they run a program written in C to test performance running in serial (on one ARM CPU core) and then in parallel (on all 16 risc cores). Both times finding the prime numbers between 0 and 16 million.
Results are:
  • Serial: ~4min
  • Parallel: ~18sec
So decided to do the same on the Pi, though using Go rather than C as it is easier to spin up multiple threads in that language. Go is not quite as efficient as C, so some performance is 'lost in translatation' as it were. But the difference should be minimal.

Also a shoutout to /u/siritinga who helped me getting it working as intended and as efficiently as possible.

Full source (and a native ARM rPi binary if not wanting to compile yourself) on github

Final on Raspberry Pi 3 result was:
  • Serial: ~2min19sec
  • Parallel: ~58sec
Not bad! The Pi 3 is much faster in single thread - but not surprisingly slower in parallel. Taking about 3 times as long with 1/4 (4 vs 16) of the cores compared to the Parallella :)

edit: Upping the number of Go Routines to 16 reduced the result down to 53 seconds - shaving 5 seconds or nearly 10% off from when only running 4 Go Routines.

Will look into actual optimizations rather than just throwing more threads at the problem...

20170306

Mastermind Game #4: Input flow done

ARDUINO: Contrary to originally planned, the random assignment of the solution and the routines to check the players guess towards it have been pushed to the next update. Before that get put in, it made sense to finish up the general flow of input and storing the history of guesses in a game.

And it was quite the little brain-teaser. I totally overthought the problem. Juggling an array-slice around for the editing part, and then push that to the history array. Which caused problems when browsing the history and deciding to go back to edit.

A little rethink later, and keeping with the adage that simpler is better, I decided to do the edits directly on the last entry of the main history array. A little fiddling about later, it was all working as intended. Mind you, all in all a good few hours went the way of the dodo before I got that far.

Github repo for this stage.

At this point I may as well go a bit into depth on how it is all controlled. Inside the state_t struct, you'll find there is a variable named mode which is defined earlier as an enum. This to make the later main gameLoop switch more intuitive. I could have just used a number from 0 to 2 to jump between modes, but having named values makes it so much more readable.

Out of the state_t struct I make an instance of which inside the loop() namespace called state for passing along to where it is needed. This to avoid using globals. Globals are by and large evil. Passing data by value or reference is much safer. That way, one can control which functions can only make local changes - and which can manipulate the data so it also effects other functions.

Further on - each mode got their own little function, that will run as long as the variable switchMode in the state instance remains false. Once the user do the action to proceed to another mode, this is set to true, and the game jumps to whatever mode is then set in the mode variable in the state instance.

What mode to go to will vary a bit depending on both what mode one is in, if it is the first turn or if it is the last turn. In edit mode, one can only go to browse mode - unless in first turn. In which case it makes no sense to browse the history, so one is taken directly to the commit mode. This is handled by this ternary expression:

s.mode = (s.tries > 0) ? browse : commit;

Which do the same as the more verbose:

if(s.tries > 0){
  s.mode = browse;
} else {
  s.mode = commit;
}


Likewise, in the commit mode if one is at turn one and try to go back to browse, it is denied since there is no history to browse. Come to think of it, I should add an else there (or do another ternary) to throw the player back to edit of the first turn. Though shouldn't matter. The first turn will be a wild-ass guess at any rate, as there are no clues to go by.

When in browse mode, one can go back and forth in the history. If pressing the select button whilst not at the most recent entry, one is taken back to edit-mode and can make a change to ones current guess. If pressing the select button whilst at ones most recent guess, one is taken to the commit mode.

In commit mode, one can confirm the turn by pressing select - or go back to browsing by pressing the go right button. It may be a bit superfluous, but I like the added confirmation or go back option this mode provides.

And that is as far as I've gotten. Still not at the stage of being playable - even through Serial-monitor. But now all of the basic structure and setup is complete. So next time, the random colours selection will be put in, and the routines to compare the guess to the solution and store the result in the history instance of the ledOut_t struct.

Maybe even start to breadboard up a few LEDs and hook up the Shift-Register - but I'm not promising anything :)

20170226

Mastermind Game #3: Getting started with the code

ARDUINO: Allright, now that all is well planned out, it's time to flesh it out a bit by means of actual wiring up stuff, and write the code to run it. It'll all be done in steps adding one feature after the other in separate writeups so as to not get ahead of myself.

Today, the basic structure of the code and getting the buttons to work as intended. First off I believe the source code of this project to get rather big - in Arduino terms - so I've split it up into three files so as to be easier to navigate.

- mastermind.ino
The main file. Contains all the various definitions, setup and loop. Note here that I've structured it in such a way that loop() will never actually do just that. Inside it I got some initializations, and then an endless loop using a while(true){} loop to take care of business resetting values on new game and then get the game going. The game-loop itself is separated out into a separate function

- chores.ino
Contains various helper-functions to make it all work as intended. This is where most the logic work is done. Keeping up with and setting state, feed data to and from structs and arrays. You know, all the fun stuff.

- inOut.ino
The nuts and bolts level of the operation. Reading buttons, control the shift-register to change LED output and such. If there is something to be done with the actual hardware, this is where it'll be at.

Github repo for this stage.

Mind you, when using several files like this - it do not work quite as in other more 'professional' development environments. The extra files are not packages unto themselves that are fully enclosed bar the functionality and structures you make public for export. No, in the Arduino IDE it just means that at compile time, the IDE will collate all the files in the project, and treat them combined as one big file rather than several smaller.

So whilst you do not have to worry about transporting data around or import supporting files - you pay for it in lack of encapsulation and separate name-spaces.

In its' current state, it'll read the buttons, and allow navigation to change colours of the players guess and proceed to the next stage.

Breadboard wiring for this stage:



Using button left and right you traverse the LEDs. Hitting button select, you change color 0..5 by hitting button left and right. When happy with the choice, hitting button select will take you back to traversing the LEDs again. When traversing, one can also get to the 'next stage' option by being off the right 'edge' of LEDs.

Mind you, no LEDs are actually hooked up yet, so everything is 'emulated' by dumping the values of internal state to the Serial-monitor.

The next update will flesh out some more functionality. Probably the random assignment of colours to the game solution - and the routine to check the players guess up towards the generated solution, and display the result.