Thursday, December 17, 2015

Norfolk Island's Phantom Browsing

This might just be a very subtle troll, and if it is then huzzah's are in order to whomever put it together.

I was checking out the browser usage page on Wikipedia and noticed they have a map showing the most popular browser for each given country.


That's pretty neat but wait... is that PhantomJS at the bottom?

PhantomJS, for those unfamiliar, is a headless webkit implementation which means it's sort of like a browser but doesn't have a display. Not having a display makes it great for things like automated testing but super difficult to use as a day-to-day browser.

Initially I didn't see any countries with that brown color indicating PhantomJS but upon closer inspection I saw this:

Can't see any land under the dot, but there must be something there... let's check the area in Google Maps


Hmm, nothing there, let's zoom in...


I think I see something there...


Norfolk Island is something like 10km across with a population a little over 2200 people. You might not have heard of them because they seem to be trying to use PhantomJS to browse the internet ;)

I'm curious how they found the PhantomJS project in the first place, does it come pre-installed on computers in Norfolk? This is what I call internet hard mode, kudos to them.

Note: I'm assuming there is just a server farm here that runs lot of automated tests (maybe bots?) but it's just so much more fun imagining a bunch of confused people fiddling around trying to browse reddit with PhantomJS.

Monday, November 19, 2012

Baseball ELO fun

This is mostly just a placeholder for now, I ran all the game results for the 2012 season through a simple ELO generator I wrote. Here are the preliminary results:

American League      National League 
OAK 1320.1           ATL 1266.43
BAL 1286.49          SF  1266.01
LAA 1274.66          WAS 1261.66
TB  1271.04          CIN 1238.35
NYY 1270.66          MIL 1230.31
DET 1249.01          PHI 1226.64
TEX 1237.41          SL  1223.88
SEA 1198.28          LAD 1219.55
CWS 1189.35          SD  1216.5
TOR 1175.02          ARI 1188.84
KC  1164.9           NYM 1139.73
MIN 1126.35          COL 1129.06
CLE 1116.02          FLA 1121.09
BOS 1105.49          PIT 1116.45
                     HOU 1089.87
                     CHC 1080.85

These numbers are a straight win/loss record ELO with a K-rate of 15 and nothing else taken into account. I'm going to try and find time to make some sensible adjustments for things like home/away advantages and possibly scale the K-rate as the season progresses.

Nate Silver did something very similar a while back that can be found here: http://www.baseballprospectus.com/article.php?articleid=5247 but hasn't really been kept up to date that I found, there may also be some additional objective measurements that can be used to improve it now.

Data from the one and only retrosheet:
http://www.retrosheet.org/gamelogs/index.html

The information used here was obtained free of charge from and is copyrighted by Retrosheet. Interested parties may contact Retrosheet at "www.retrosheet.org".

Edit: charts and graphs as promised

Charts and Graphs:

Distribution

ELO Distribution grouped by 25 points
The first graph is a distribution graph. In games like chess we'd like to see a nice bell shape indicating a normal distribution with a few really good players and a few really bad ones and the majority somewhere in the middle. For baseball though, that doesn't quite work. There could very well be 50% of the teams that are heads and tails above the rest and evenly matched amongst themselves. Trading or not signing stars in hopes of building for the future can leave a significant number of teams near the bottom as well.

Method

I initially did 2 Distribution graphs, with the first one grouping the teams by 50 points and the second grouping them by 25 (shown above). While the first one looked like a bell curve with a chunk taken out of it the second is much more interesting as it really shows the divide better. The groupings were done starting with the indicated ELO and including all teams at that level up until the next one, so a team with 1149 would have been counted in the 1125 group in the above chart.

Analysis

There really seem to be 2 or 3 groupings of teams. Some (~9) bad teams, some(~8) average teams, and a lot (~13) of good teams, including one outstanding team: Oakland. This is more or less what I would have expected.

More to come...

Here's a sneak peek for AL East fans (you can use the slider on the bottom or zoom in out in the top left):


Tuesday, August 14, 2012

Bar A Jeux in Montreal

I promise I have some upcoming posts on some Arduino projects and gaming stuff, but while I was in Montreal last month for a Refused concert I was fortunate enough to catch some of the Just for Laughs festival.

Apart from great comedy the Just for Laughs festival really takes over a good chunk of downtown Montreal and features all kinds of events and buskers and cool stuff... and food trucks, delicious, delicious food trucks.


One of the really neat things that I almost missed (A friend actually noticed it) was the "Bar A Jeux", which, despite my tenuous grasp of the French language immediately piqued my interest.  They had a dozen or so tables set up with umbrellas and chairs and a booth full of boardgames. We walked over to have a look and a super friendly young man asked us if we'd like to learn how to play a game.


I took a quick glance at the selection for something quick (we didn't have as much time as I would have liked) and noticed a couple copies of Zombie Dice on the shelf along side dozens of other dice/card games and even some more significant games like Agricola and 7 Wonders. Having seen Zombie Dice on an episode of Table Top and being interested in it as a quick game that my friend (not a boardgamer) might enjoy that was our selection.


The volunteers offered to come over and show us how it worked which would have been super helpful if I wasn't already familiar with the game. I asked if they needed my id or a CC number or something but they just said to bring it back when we were done with it, another small gesture that I appreciated. It was really nice to see how excited they seemed to help people learn about some of these cool new games and to see how many people seemed interested in sitting down and learning/playing.

Zombie Dice was a fun game, we played through 3 times while enjoying shade and a couple beer. The booth supplied a nice little dice box which made playing on the smallish tables very easy (Agricola might have been a challenge to fit).

After we were done I asked if it was possible to purchase a copy of the game from them and they said they weren't selling them but there were a couple games shops (and apparently a pub that has games which I really wish I had time to visit) around that sold them.

Next to the boardgame booth was another booth with wooden dice games and magnetic foosball/hockey type games and some neat puzzles. There was also a large game with a balancing platform and odd shaped blocks that people were playing with, like some sort of super-sized tip-it game.


I hope they bring this back for future festivals, even if I can't make it there it's great just to know that somebody is getting to sit out in the shade and learn a new game. Thank you Just For Laughs.

Thanks,
Brent

Thursday, May 17, 2012

Symmetric Pandemic

Pandemic is a very popular board game around the office, but there are a couple things about it that bug me.
First, I'm pretty competitive so even though this co-op game can be a real challenge I really wanted to find a way to pit players against each other (other than using the bio-terrorist role). The other thing that has always bothered me a bit about pandemic is that one or two vocal (hopefully experienced) players can often drown out the other players. I've occasionally considered granting each player a certain amount of time per round/game and using timers to limit an individual's vocal contributions but this kind of takes away from one of the most fun parts of a good game of pandemic, the interaction and debate.

A colleague of mine, Mike McGraw, proposed an interesting twist on the game that seemed like it might solve both of the above issues. We had multiple copies of the game, what if we could sync up the decks so that we could have 2 teams simultaneously playing the same game? Because of the way that pandemic works it would be relatively easy to have both teams get the exact same player and virus cards in the same order. This means that the decisions made by the teams would be the sole difference in the results of the games. A nice even playing field. We decided that the winning team would be the team that cured the most viruses, if both teams won, then the team that won first (real time, not turns) would be the victor. This incentivised both teams to play at a quick pace, but not a reckless one.

A nice side effect of having both teams play on the same (large) table and use the same card order is that at least at the start of the game you don't want to talk too loudly or too much about the cards you draw or the good ideas you have because your opposing team can also hear them and use that information. While I don't think either team used this advantage to any great degree in our game it's an interesting dynamic.

Once we decided to give this variation a try we didn't want to have to require an extra person on hand to do the initial deck sync and make sure the post-infection shuffles also resulted in the same ordering. Fortunately I work in an office full of talented programmers, one of whom (Luke Dewitt @whatadewitt) spent a couple hours building a web-app that takes a seed and generates a shuffled deck of pandemic cards, has buttons for drawing from both the player and virus decks and manages the actions required for infection events. We had 2 computers load up this app and input the same seed and the resulting play through is symmetrical (in terms of cards drawn).

Luke's Pandemic Card-Sync-app


To make it a little easier to get the app running in the limited time we had before playing we decided to remove a couple special event cards that can affect card drawing which could potentially break the drawing symmetry. Since you only play with a subset of the special event cards anyway this shouldn't be a problem.

The game itself went really well, my team had to restart after a missed turn early in the game, but this was easily accomplished using the app and the same seed and we quickly caught back up to where we were before. The game ended with one team curing the last virus and winning by being the first to do so. I'm confident that both teams would have won the game (we were playing with 4 infection cards for this initial play test) so the real-time aspect of the variation made the difference.

The 2 Teams and Boards


We plan on playing another game like this sometime soon, if it turns out I'll record it and post it here. I think everyone enjoyed the game and the new angle that the 2-team variation brought. One thing we've considered for future iterations is finding a way to track (or perhaps record) which moves each team made so we could review it post-game and find the turning points.

In particular I like the idea of picking a seed at random, generating a unique game and playing it either with a group or solitaire (Pandemic is a great solitaire game) and then sending the seed to a friend to see how they did with the same card sequence.

Thanks to Luke, Mike, Shawn, TJ, and Jamie for the great game,

Brent

UPDATE:

Luke has posted the source for the web-app on github and it's also available on his site:
source: https://github.com/whatadewitt/symmetric-pandemic
online: http://whatadewitt.ca/pandemic/

I'd recommend playing (or at least starting) a solo game before trying a multi-team setup just to make sure you understand how the app works.


Wednesday, April 11, 2012

Super Mario Kart Cycle



I love Super Mario Kart and the SNES in general.


When I was young I used to think about how much fun it would be to play SMK with a real bike. Now, many years later, we finally have the ability to create such a thing without a lot of very specific knowledge and tools.

Some of the things I used:
Arduino microcontroller (UNO)
A few transistors
Some pushbutton switches
A few resistors
A 2$ photo interrupter
An SNES controller
A very old stationary bike
A breadboard


Nothing there is overly expensive and none of it should require more then a little time and googling to figure out how to use. That said I'm not particularly experienced with electronics so there may very well be better ways to do some of this. (Actually I've found a few things I'd like to correct myself quite recently)

This was my 2nd Arduino project, the first being an n-back test game which I'll make a post about in the future (https://github.com/statuswoe/nBackGame).

There are two separate parts to this project, the first is finding an easy way to output from Arduino into the SNES and the second is having the Arduino recognize when the bike is being pedaled and when the buttons are being pressed.

Arduino to SNES

The SNES controller isn't particularly complicated, there looks to be a multiplexer and a couple resistors but little else. I wasn't able to find a really good diagram though. There is a description of the pinouts here: http://www.gamesx.com/controldata/snesdat.htm but I wasn't really interested in playing with a clocked signal when I didn't have to since I had an old SNES controller that I wasn't using. All I needed to do was put an NPN transistor across the points that the buttons contacted and I can fake a button press by applying voltage to the base pin, this was pretty simple.

My soldering is getting a little better, couldn't get much worse.


What I ended up with is a series of input pins that I plugged into my Arduino board and when I set them high the associated SNES button is triggered.

I mounted the project board and the modified controller into a small toolbox which was the cheapest container I could find that fit them both. The SNES connector comes out of one end and the Arduino connector comes out of the other. One of my goals was to make the SNES controller adapter entirely separate so that I can use it for other games/peripherals.




Bike to Arduino

The Handlebar buttons are pretty self explanatory. I used momentary push button switches that are on unless pressed just because I had some on hand. Because I'm running them into the Arduino I was able to invert the state in software.

The fun part was finding a simple way to track pedaling. I found a few caveats:
- Because the wheel doesn't stop when you stop pedaling and there are no real breaks I didn't want to use the wheel to track speed. I need to know when the user stopped pedaling.
- Running wire onto the pedal would be a pain because the pedal rotates relative to the bike so I'd need to set up brushes or something that wouldn't twist up when you pedal.

Because of these issues I decided to mount a photo interrupter next to the sprocket and have something attached to the sprocket at regular intervals that can pass through the interrupter and trigger the state-change. I ended up using 6 small pieces of playing card to do this.


Once the photo interrupter and buttons were hooked up to the Arduino I wrote some quick code to read the inputs and set the appropriate outputs to the SNES Controller adapter. The code is available here(and could use some polish).

I have the code and SNES Controller adapter set up to accept up, down, left, right, A and B, but I don't have the up/down hooked up to the bike yet because I'm not satisfied with the toggle switch I was going to use for it.

So in the end we have The Bike pushing data into Arduino, which does a little logic and sets some appropriate outputs which saturate the transistors to press the appropriate button.





EDIT:
Maicol asked for some more info on using transistors to control digital buttons, so here's a better image of that part of it, click on it for full size. The common ground is the red blocks, the blue side is the per-button input from the arduino (high to simulate the push).  The NPN transistors bridge the path from the (green block) SNES controller wires to ground which the SNES reads as a button having been pressed.
The SNES is a bit odd in this sense, what you really want to do if you're using this for any other sort of input is put one side of the NPN transistor on the wire leading into one side of the button and the other side of the NPN transistor on the wire coming from the other side of the NPN transistor. You can then apply a charge to the middle pin of the transistor and it will act as though the button had been physically bridged. Hope this helps.


Friday, April 29, 2011

The value of a drop in a bucket

I frequently listen to the ESPN podcast "Baseball Today" with Eric Karabell and guests. It's not my favorite podcast, but the guy knows his baseball and his co-hosts are usually really good.
On a recent podcast Eric mentioned that the current decline in attendance at Dodgers games being partially blamed on fans wanting to protest the ownership was silly. He stated that a fan not going to a game to protest the ownership situation wouldn't even be noticed and that no real fan would want to do that.
This reminded me of something else that's been getting a lot of attention this (and every) election season, the value of one vote. On a larger scale the concept is often likened to a drop in a bucket, an idea worth looking at.

The price of a coffee:

If I asked you right now the exact maximum price you would pay for a coffee, to the penny, what would you say? Do you think you're guess is accurate? In my case I'd have to say no, it's just a ball-park of what I would expect, rather than an instantaneous reflection of how much I would actually pay. It's really hard to prove the exact price you would pay for something at any given time since any initial offer or haggling would likely change your perspective.
However, If I had 1000 clones of you, all of whom are exactly like you in every way and offered them all a different price for a cup of coffee then I could find out exactly what your maximum price would be. Consider the following example

Clone 1 is offered the coffee for $.01 and accepts
Clone 2 is offered the coffee for $.02 and accepts
...
Clone 143 is offered the coffee for $1.43 and accepts
Clone 144 is offered the coffee for $1.44 and declines
...

We can expect that since clone 144 declined to pay $1.44 for the coffee that all subsequent clones, being the same person effectively, would decline to pay more. At this point we know that the maximum price you (being the one who was cloned) would pay for a coffee at this time.

This kind of accuracy is impossible to get simply by offering a person the same coffee consecutive times since as I mentioned earlier previous offers can bias their perceived value of the coffee. It also doesn't last, ask me 5 minutes from now and I'd bet the number would have changed, particularly if I was still growing thirsty.

Now you might be thinking "Wow Brent you've wasted like 3 minutes of my day, thanks! Who cares how much I'd have payed for a coffee at a specific time, other than perhaps the man running the coffee shop at that time. Also, since this is a theoretical experiment I can't even find that price in the real world rendering this whole post useless. I hate you." Ouch. Well, maybe we can use this idea to help increase our perception on the value of one penny/vote/drop?

Consider that not every person would have the same "instantaneous maximum" for a given offer or question. The "Would you pay $1.73 for a cup of coffee." question could easily translate into "Do you consider Party X, who got 10,173 votes to be a valid party worthy of consideration in the next election?" or "173 people complained about a decision I made, is that number high enough to make me take their perspective into consideration?" All of these numbers could easily fall into the instantaneous maximums of people looking at them. For example:

Party A received 10,417 votes
Party B received 9,567 votes
Party X received 4,351 votes


Party A wins the seat, Party B supporters are disappointed about losing such a close race, but know they have a shot next election. Party X however didn't really come all that close, so they might be asking themselves a big question.

Did my vote count for anything?

One way to look at it is that in such a close race both of the top parties will be looking to gain votes in the following election, one way to do this is to make sufficient concessions toward an outside party's platform to woo some of their voters. For instance if Party X was really pro-environment then Party A or B might alter their platform a little to be more environmental in order to get a few of Party X's votes. This is at least a partial success since you are going to see some of your desires fulfilled.
Another view is that with any smaller party there is likely to be people who support the platform but don't want to "waste their vote" and vote strategically for whomever would be their choice of the front-runners. This seems to be a very popular way to vote, most people feel very strongly either in favor of or opposed to the incumbent and want to make sure "he/she does('nt) get back in". What can get lost in this is the idea that a third party that loses a lot of votes to strategic voting can end up looking much further out of the running than their actual support would be. Each vote for party X adds increased likelihood that when the results come out that party would look like they have a legitimate chance in a future election.

This is where the instantaneous maximum concept I mentioned above comes in. In the sense of voting, where everyone can see the resulting vote totals and decide for themselves if a party had enough to be considered a viable choice in future elections that's a lot of potential voters using their own maximums to make that call subconsciously.

As an example if I was a party X supporter, but voted A strategically and tuned in to see the vote totals I have a number, albeit a number I don't consciously know, where I would realize that party X might have a shot next election. Say that number was 4,352 then in the above example I wouldn't yet be convinced and would likely vote strategically next election, but I wouldn't know exactly how close I came to being convinced. Now consider there are a large number of people like me, but who's number is slightly (or significantly) different than mine. This means that instead of having one solid number (to win the election) that if you miss you feel like you've wasted your vote you actually have hundreds or even thousands of numbers where your single vote could influence the next election in a much more dramatic way.

This kind of thing can snowball too. If my vote this election catalyzes additional people to consider party X and maybe vote for them in the following election then their votes can do the same in subsequent elections.

In conclusion even though third party vote totals might not win them an election, the value of the actual vote count (or penny charged, or drop added) can have direct impact on results even if the number seems arbitrary.

I didn't really intend for this to become so much about voting, but it seemed a decent example, and I think it's important that people consider not only the short term outcomes of elections but use their votes as a path to the future that they want.

Thanks,
Brent

Thursday, March 3, 2011

Maven Release and Directory Locations

A co-worker of mine ran into a strange error while running a maven release:prepare goal on a new project we were setting up, and the issue is kind of odd.

When he ran the prepare goal he would quickly get (on the first module) this error:
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] null
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.NullPointerException
at org.apache.maven.shared.release.util.ReleaseUtil.getBaseWorkingDirect
oryParentCount(ReleaseUtil.java:233)
at org.apache.maven.shared.release.phase.RewritePomsForReleasePhase.tran
slateScm(RewritePomsForReleasePhase.java:109)
at org.apache.maven.shared.release.phase.RewritePomsForReleasePhase.tran
sformScm(RewritePomsForReleasePhase.java:62)

Google didn't really help much so I had a look at source for those classes and tried to figure out where the null was coming from. While I was looking around I remembered that he had checked out the project into his root directory, so the working directory was directly inside "C:\".

That is:
C:\project\pom.xml was the top level pom getting built.

Since the release plugin looks for some base and parent directories I wondered if this made a difference, if asking for the base directory and just getting "C:\" was an issue. I tried to run the same goal on my machine, with a more nested working directory and it finished successfully. We tried adding one level of directories between his root and his workspace (C:\blah\project\pom.xml) and that seemed to do the trick.

I've logged a bug report with the maven release plugin about this: http://jira.codehaus.org/browse/MRELEASE-663, but in the interm if anyone runs into it just make sure you aren't doing your dev too close to root.

Thanks,
Brent