Objective C Builder Pattern play

April 12, 2014 by

So I read two posts on the Builder Pattern from Java today that got linked to off of Twitter.

This by Klaas Pieter which referenced this one by Uli Kusterer.  Both good articles.

I haven’t done Java much at all for the last 10 years and so am not used to this pattern, but I thought about how I might do something similar and while I’m not sure my first thought is any better, it seems to meet the requirements and/or benefits noted by the two blog posts in question and the tweet discussion referencing them.

Instead of:

 Pizza pizza = new Pizza.Builder()
     .size(12)
     .pepperoni(true)
     .mushrooms(true)
     .build();

(from Uli’s post), or

  Image* theImage =
    (new Image.Builder)->SetWidth(100)
    ->SetHeight(80)->SetDepth(8)->Build();

(from Klaas’ post)

I tried something like:

Foo * aFoo = [Foo fooWithData: @{
     @"width" : @21, @"height" : @22 }];

Here’s one way to implement that – there are multiple, clearly
(pardon the formatting, trying to fit into our narrow blog them is annoying):

// .h file
#import <Foundation/Foundation.h>

@interface Foo : NSObject

+ (instancetype) fooWithData: (NSDictionary*) initParams;

@end

// .m file
@interface Foo ()
@property (nonatomic, assign) long width;
@property (nonatomic, assign) long height;
@property (nonatomic, assign) long depth;
@end

@implementation Foo

+ (instancetype) fooWithData: (NSDictionary*) initParams
{
  Foo *result = [[Foo alloc] init];

  // If one uses setValue:forKey: in a loop as
  // as Uli notes then we can't support integral
  // properties like ints.
  // Also doing it explicitly as below
  // means we don't have to have the same name
  // for our private internal properties as we
  // document for our public parameters because
  // we can map them here.
  // e.g.,
  //  result.imageWidth = [initParams[@"width"] longValue];

  if ( initParams[@"width"] != nil )
    result.width = [initParams[@"width"] longValue];

  if ( initParams[@"height"] != nil )
    result.height = [initParams[@"height"] longValue];

  if ( initParams[@"depth"] != nil )
    result.depth = [initParams[@"depth"] longValue];

  return result;
}

- (instancetype) init
{
  self = [super init];
  if ( self )
  {
    // init with defaults
    _width = 10;
    _height = 10;
    _depth = 1;
  }
  return self;
}

- (NSString*) description
{
  return [NSString stringWithFormat:
           @"Foo: (%p), width: %ld, height: %ld, depth: %ld",
           self, self.width, self.height, self.depth];
}
@end

// main.m
#import <Foundation/Foundation.h>

int main(int argc, char *argv[]) {
  @autoreleasepool {
      // note no depth specified, taking default of 1
    Foo * aFoo =
      [Foo fooWithData: @{ @"width" : @21, @"height" : @22 }];
    NSLog(@"aFoo: %@", aFoo );
  }
}

Paste the above into CodeRunner and run it and you get:

2014-04-12 16:22:38.918 Untitled 7[71144:707]
aFoo: Foo: (0x7f8842c0af00), width: 21, height: 22, depth: 1

In the above I only typed in the class method as taking the full parameter list but normally I would have made the init method take the same parameter and do the initialization & mapping there. Something I’d likely add if I was going to actually use this, which I’m not likely to. Why not? Because to use the construct above you’d have to document the parameter keys available to use in the dictionary and what type of value each takes. This is where ObjectiveC’s named parameters comes in handy: they are self documenting.

Anyway, an interesting procrastination from what I was supposed to be doing this Saturday afternoon… :-)

7DRL 2014 – Day 7: In which everything is complete

March 15, 2014 by

Trinkets – the roguelike game I’ve spent the past week creating for the 7DRL competition – is finished, about 20 hours before the deadline! It’s a game about wandering an extra dimensional vault, acquiring trinkets and trying to get back home.

A build for mac is available here. Unfortunately, there’s no windows/linux build, but if you’re on one of those operating systems and want to play, the source is available here.

Screen Shot 2014-03-15 at 2.38.31 PM

… which turns out to be entirely justified.

My high score is 59 – can you beat it? If so, let me know in the comments below!

7DRL 2014 – Day 6: In which victory approaches at high velocity

March 14, 2014 by

One day remains, and I’m actually almost done. It would be nice to redo the map generator, and game balance can always be tweaked some more, but the plot and endgame are implemented, the boss-fights are done with basic AI, and there’s even a score feature. Shown below is the second of four boss fights:

You have a bad feeling about this level...

You have a bad feeling about this level…

… which turns out to be entirely justified.

… which turns out to be entirely justified.

7DRL 2014 – Day 5: In which parkour is performed in fancy shoes

March 13, 2014 by

Today was very productive; I finished the procedural generation of trinkets (for now, at least), improved the magic system, procedurally generated strangely worded descriptions of said trinkets, added new effects including knock-back and circular slide, and added all of the non-boss enemies, including the Abberant visible below:

Image

Parkour shoes acquired!

Shown above is the non-procedurally-generated description of one of the coolest shoe types in the game (thus far, at least). These shoes allow you to run along walls, moving faster than enemies or even jumping over them.

I still have two more days left to go, and quite a bit still to do, including:

  • Plot
  • Victory conditions
  • Boss fights + Boss AI
  • Game balance
  • Prettier maps

I think Craig is right on track with his wearables & Apple

March 13, 2014 by

I think Craig Hockenberry @chockenberry is right on track with his Wearing Apple post.

I’ve been thinking and talking about a “personal secure network” among a collection of devices you are wearing or carrying for a while now and it seems like a no-brainer to me.  Seems totally silly to put all the battery, radios, antennas, storage and whatnot in a single device (google glass for example).

You need less battery in what I call the ‘motes’ if the LTE/WiFi radios and antennas are in the ‘core’ (“hub” in Craig’s post). What are ‘motes’ ? Think rings, earrings, necklace, bracelet, phone in pocket, flexible battery in belt, piezo generator in shoes, motion generator in umbrella/walking stick, bluetooth earpiece, display in glasses and/or contacts, high performance computing cube in our backpack, and sure, even a watch :)

What’s the problem with this vision? Lots really :)  Charging all these devices will be a pain.  Clearly you need something like a flat pad you set ‘motes’ on while you sleep and they charge inductively.  Better yet would be if they had small energy harvester chips with fractal antennas that harvested ambient energy (microwaves, cellular signals, AM, FM, etc) to extend their battery life.  Oh, yah, better batteries would be a big win and this may not get cool until that happens.

Want to get even more “out there?” Check this out:  Sugar-powered biobattery has 10 times the energy storage of lithium.  Pretty cool but one of the implications of this might be devices that could be powered from our body’s internal processes directly.  So to charge your devices you just eat more.  Be a boon for obesity.  Need to lose weight? Play more flappy birds!  :-P

This then lets us surgically implant devices so you don’t have to worry about forgetting it at home.  You may think I’m being silly, but the convenience will win people over.  Also, note the long-time existence and surgical implantation of pacemakers & defibrillators.  Then look at how common tattoos and body piercing are in youth today (in parts of the USA anyway).  We are not that far from this.

Ok Geek’s hungry so leaving it at this quick “jot this down” for now.

7DRL 2014 – Days 3 and 4: In which trinkets are created

March 12, 2014 by

So, I’m about halfway through the week, but days 2-4 were all mostly occupied by other things, so the real productivity is just beginning. I’ve reworked the combat system to use the same generalized targeting/effect model as the spells. I’ve also changed trinket abilities to work on that model, divided trinkets into six types (hats, orbs, wands, cloaks, weapons, and shoes), which can be equipped and used for various nefarious purposes. I’ve started work on the procedural generation of trinkets, but there’s still a lot to do on that front, which will occupy the next day and a half, leaving me with a day and a half for enemies, plot, game balance, and a dungeon generator that isn’t stolen from the libtcod tutorial. That’s plenty of time, right?

Screen Shot 2014-03-12 at 11.36.07 PM

Weapons can now replace your bump attack with one or two spell casts. This one replaces your attack with two fire bolts, but they can also sunder defenses or daze and freeze enemies, among other things.

Screen Shot 2014-03-11 at 9.38.44 PM

Death Star? Death Star! DEATH STAR!
This is what happens when you procedurally generate names by picking two words from a list and concatenating them…

 

7DRL Competition 2014 – Day 2: In which the art of sorcery is practiced

March 10, 2014 by
Screenshot of Trinkets

Magic system: Activate!

There are now six spells, and status effects, and some of the ‘everything goes horribly wrong’.

The spells have all been divided into ‘targeting’ and ‘effect’ components – except for teleportation, which still consists of duct tape and hacks and probably will remain that way.

There’s also a bit more user interface than before, and the trinkets are actually worth using sometimes (even if they are all still exactly identical).

Melee combat has also been re-written to allow for spells like the Ethereal Axe, which replaces your melee attack with a high-damage Arcane attack.

Tomorrow, I’ll be working on equipment. I won’t have much time though – classes and whatnot – so there probably won’t be a blog post.

The day after, procedural trinkets, more enemies, and everything going even more horribly wrong!

7DRL Competition 2014 – Day 1: In which a roguelike is begun

March 9, 2014 by

This year I’m participating in the Seven Day Roguelike Competition, a contest to make a game in the roguelike genre in a week. (For those not familiar with it, roguelikes tend to be dungeon-crawlers with procedurally generated words, permanent character death, and often old-school graphics. There are frequently some variations from this rough description.)

I’m making a game known as ‘Trinkets’ until I think of a better name. It is a game in which a wizard strapped for cash loots a pocket dimension, and everything goes horribly wrong. It will experiment with a nontraditional power progression; you become weaker, then strong again, rather than a constant power level or steady increase. There will be a plot and randomly generated Trinkets.

My time will be somewhat limited, as I am currently a college student, but after spending most of today programming I produced the following:

Screenshot of Trinkets

Taste the power, troll scum!

I’ve used some code from some past projects, specifically most of the data structures and UI code. I’m using python, with the libtcod library.

Current features:

  • Move around…
  • …on a procedurally generated map…
  • …and hit things…
  • …which hit you back, and can kill you if you’re not careful.
  • Look for trinkets…
  • …which have magic powers…
  • …which are simply not as powerful (at least for now) as your spells.
  • Speaking of spells, you have five (and will have six), which in combination make you nearly unstoppable…
  • …at least until I implement the ‘everything goes horribly wrong’ part.

Brother® stops & refuses to print. Annoying! So I hack their TN-360 toner cartridges to get all the toner in them.

March 2, 2014 by

I purchased a Brother® MFC-7840w multifunction laser printer some years ago and I have to say that it’s one of the better modern printers I’ve owned.  Mac OS X software for it isn’t great (buggy), but it’s better than most of the others I’ve tried and the printer performs quite well.  I’ve been recommending them to anyone who’s asked me (and I get asked quite a bit).

After finishing the small starter toner cartridge they supply with the printer I put in my first TN-360 “High Yield” toner cartridge which claims 3500 pages under “normal use”.  I use this printer under what I’d consider normal conditions – mostly simple text documents.

Worked well but all of a sudden it just stopped printing with a message about the toner needed to be replaced.  “That’s odd,” I thought to myself.  “I’ve owned a lot of laser printers over the last 22+/- years and they’ve always started gradually printing more and more faintly when the toner was running out and I’ve never had a printer just refuse to print until I changed the toner cartridge before! Seems pretty heavy handed.  Then I calculated the number of pages it had printed (2120) and had an uncomfortable thought: “If they just stop and refuse to print and the printouts were looking just fine right up until that point, how do I know it’s really out of toner?”

I didn’t get my money’s worth and the forced toner replacement was feeling heavy handed and annoying.  So I wondered, “how do they decide to put up that alert anyway?”  Pulled the toner cartridge out and started examining it looking for electrical contacts (sensors inside?) or some other mechanism.  I found this:

IMG_3142

Note the arrow.  It’s pointing to a clear plastic “window” on the right side of the toner cartridge when you’re looking at the top from the front where the handle is.  It appeared like it might give the printer an optical view into the insides of the toner cartridge. “Ah HA!” I thought.  Small piece of Gorilla tape (sticks much better than electrical tape) later and I had this:

IMG_3140

Put it back in and time for a test…

Printer prints PERFECTLY… We are being ripped off by Brother and that really sucks.

This fixed worked for another 1001 perfect printouts and then it stopped again…

“DANG IT! The printouts were still looking *fine*!”

Take the toner out to put in the replacement and notice something on the side when you’re looking at the bottom:

IMG_3145

There’s Another Sensor Window!  (With Gorilla tape on it in this image).  Here’s a close-up:

IMG_3144

This piece of tape added and, sure enough, working FINE again… ARG FARG SNARG – BROTHER!  I want to like you but this is robbery!  AND it’s bad for the environment which makes it even more offensive.  Rarely do I want to call for a class action lawsuit, but this situation was definitely making me feel that way…

How many perfectly fine beautiful printouts did I get after blocking the second window?  I can’t tell you yet because it’s still going strong 200 sheets later.  :-/

So, if you want to get the full life out of your Brother TN-360 High Yield printer cartridge you may want to pick up a roll of Gorilla Tape and prepare to “fix” the cartridge.  Be careful to make sure the tape is stuck on there will because a loose piece of tape being drawn through your printer will probably do bad things to it (Follow these instructions at your own risk!).

Please add a comment if you try this with a different printer model and it works for that one also; likewise for other Brother toner cartridges. Thanks!

Cheers.

Note: All trademarks noted are the property of their respective trademark owners.

Simple BBEdit Text Filter that’s been useful: PrettyJSON.py

February 18, 2014 by

Dad’s been working with some JSON output from a web service lately and it comes back lacking line-feeds and indentation which is great for transmission but hard to read for humans.  Dad’s not a python programmer and Geek’s busy writing a Humanities 110 paper, but the simple python script PrettyJSON.py (below) seems to work if you put it into

~/Library/Application Support/BBEdit/Text Filters/

It can be used to beautify the front window in BBEdit if that contains JSON:


#!/usr/bin/env python
import fileinput
import json
if __name__ == "__main__":
  jsonStr = ''
  for a_line in fileinput.input():
    jsonStr = jsonStr + ' ' + a_line.strip()
  jsonObj = json.loads(jsonStr)
  print json.dumps(jsonObj, sort_keys=True, indent=2)

Because Bare Bones Software is so cool this works with their free Text Wrangler editor as well except you just put the files in

~/Library/Application Support/TextWrangler/Text Filters/

instead, as one would expect.

This gives you a new item in the “Text” -> “Apply Text Filter” sub-menu named whatever you named the file (PrettyJSON.py in my case).  Open a messy JSON file, select “Text” -> “Apply Text Filter” -> “PrettyJSON.py” and watch your file contents magically become beautiful! Thanks BBEdit!


Follow

Get every new post delivered to your Inbox.

Join 1,166 other followers