Tuesday, November 10, 2009

Channel 9 Full Screen Video Player: My first Bookmarklet

I really enjoy watching videos from Channel 9, Microsoft’s community site that targets users and developers. It is a great way to keep updated on the latest technologies and learn more about future products before they come out. The only thing that I don’t like is that the website is not very user friendly for people that have multiple monitors. This surprises me, as most developers that I know use at least two monitors, sometimes three or four. Even after their recent layout change, which increased the size of the video player significantly, the embedded video player is still too small to be able to read code from screencasts. There is of course a full screen button, but this doesn’t really work when multitasking on multiple monitors as it will close as soon as you click on another browser or window on another screen. Both Silverlight and Flash have this issue, which they consider to be a security feature, but it renders the full screen mode worthless useless you stop using your second monitor while watching the video.

Currently there are only two workarounds to the Silverlight/Flash full screen issue, both of which YouTube has already implemented using buttons at the top of the video player. The first is enlarging the video so that it takes up more of the page, and the second is opening it in a new page that can be resized to as large or small as you want. Alternatively you can use a different video player such as the embedded Windows Media Player, but while the WMV links on Channel 9 display full screen in the browser they sometimes have buffering or quality issues and cannot take advantage of the Smooth Streaming that the Silverlight player can offer. All I really wanted was a way to enlarge the video to fit the full width of the browser window, so I figured why not just write a script to do it?

Bookmarklets are essentially small snippets of javascript code that live in a browser’s favorites and do simple things like opening a Wikipedia box for searching, Subscribe/Share/Note the current webpage in Google Reader, using Google SideWiki, or adding any item to an Amazon Wishlist. Due to cross-site scripting restrictions implemented in most browsers they are relatively safe, so they shouldn’t be able to drain your bank account or spam all your friends on Facebook. Plus unlike Greasemonkey scripts they will only run when you click on the link in your favorites, so they won’t slow down or change your normal browsing habits. This seems like a perfect fit for resizing the Silverlight video player on Channel 9.

So after dissecting the way that the Google bookmarklets worked I started coding my own. If you want to try it out you can simply drag this link to your favorites (or right click and select "Add to Favorites"): C9FullScreen and then click on the new link that it created after browsing to your favorite Channel 9 video. To see how it works, here is the code that gets embedded into the C9FullScreen link:

And here is the script that gets injected into the page to resize the video:

And here is the result: A full screen video... Enjoy!

Sunday, November 8, 2009

Short .Net Reflector Training Video from Pluralsight

Today’s Simple-Talk newsletter had a video from http://www.pluralsight.com that talked about the basic features of Red Gate’s .NET Reflector. If you are not familiar with the .NET Reflector, I highly recommend you give it a try, as it is by far one of the best .NET tools available. This short 14 minute video walks you through most of the features of the program and shows you why it can be so useful. I’ve used .NET Reflector for system testing or when a library’s documentation is incomplete or out of date. The video doesn’t cover the Analyze feature for finding all class references and dependencies, and it doesn’t talk about all the cool plug-ins you can add, but it does provide a great introduction to a very powerful tool! 

Sunday, November 1, 2009

Texas Holdem Hand Equity Calculation in IronPython

This year I have been working in my free time to create easy to use Texas Holdem poker spreadsheets based on IronPython using Resolver One. These spreadsheets can be used to calculate Win/Tie/Loss odds, but some people like to use hand equity instead since it represents a player’s overall stake in the pot. Equity of 1.0 or 100% means that they will win the entire pot, where as equity of 0.5 (50%) or 0.25 (25%) means that they will split the pot with other players. You can again use Monte Carlo analysis to run a number of trials before all of the board cards are dealt to estimate a player’s current equity in the hand. This means that if during 4 trials I would win 2 of them and split the pot with one other player on the other 2, then my equity would be (1.0+1.0+0.5+0.5)/4 =  3/4 or 75%.

Calculating Win/Tie/Loss statistics on an independent player vs player basis is very simple, as the player’s pocket cards are evaluated against each opponent one at a time to show which opponent hands are stronger or weaker than your own. This does not take into account how the pocket cards of other opponents might change the odds, since in reality you usually play verse a table of opponents not just one opponent at a time. Changing the spreadsheet to work against the whole table would require changing the Monte Carlo simulation from a “row by row” analysis to a “table by table” analysis, where by you setup a table of opponents using a random hand for each player given the information that you have about their hand (AK, KK or QQ, Group1, etc..) and then generate a random 5 card hand based on the currently dealt cards.

There are a lot of issues that you have to watch out for in this type of Multiway Isometric Ranged Equity Calculation, but the basics are simple so long as you have a method of comparing multiple player’s hands for a given board. The C# poker library that I use is mainly focused on heads-up hands, but it only took me about an hour to whip up a method that would take a board setup and a list of player pocket hands and return the scored value and equity for each hand as well as the highest ranked hand and a list of the winners. Here’s the code:

Here is a sample print-out when bPrintResults is True:

testBoard = ((288<< (13 * 3)) + (7<< (13 * 2))) #0b100100000000000000011100000000000000000000000000 is Ts 7s 4h 3h 2h
testHands = [3, 3 << 13, 3 << (13*2), int('1100',2)] #Hands: 3c 2c, 3d 2d, 3h 2h, and 4c 5c
(lstintScores, lstfEquity, intHighScore, lstHighScorers) = HandEquity(testBoard, testHands, True)

Start HandEquity with 4 hands and board cards: Ts 7s 4h 3h 2h
Best hand is 'Two pair, Three's and Two's with a Ten for a kicker' with 2 winner(s) getting 0.50 equity in the hand.
000: Hand 3c 2c HandScore=033622016 Equity=0.50
001: Hand 3d 2d HandScore=033622016 Equity=0.50
002: Hand 3h 2h HandScore=None        Equity=None
003: Hand 5c 4c HandScore=016942384 Equity=0.00

This is just a first step towards a full table Monte Carlo Simulator, but it gives you all of the details that are needed to find the winner(s) for a hand and calculate hand equity. The code used to generate a random board would be the same as in the other poker spreadsheets, but the player hand selection logic would need to use some sort of Round Robin algorithm to make sure that each player gets equal access to all of their possible pocket cards. Then you would use the HandEquity method to calculate the player’s equity for each hand and aggregate the results. My next goal is to change the spreadsheet code to use multiple threads, so I probably won’t tackle multi-way analysis anytime soon.

Blog.TheG2.Net - Your guide to life in the Internet age.