The Puzzle-Block challenge
I was introduced this week to a fun and great coding challenge, written by Adi Miller, a principal engineering manager at Microsoft.
(The Puzzle-Block game, taken from ituns)
The challenge goes like this - he created a graphic interface of the game, and coded the game.
Your job - create an automatic player which will get a higher average score, be quicker, or use Machine learning.
The game works randomly by a seed - the computer watch, which means you can check specific seeds in different players for an accurate results.
The code is available here:
You can either fork it, of create a branch of your own - be careful not to interfere with the master branch.
So... where should you start from?
Here is the Prerequisites:
- C# 6
- Dot net 4.6.1
Both come as default in Visual Studio 2017
Some code intro (Thanks to Chaim Gluck, also from Microsoft):
The Class game initiates a Player implementation (When you wish to test any implementation this is where you change the main to use that implementation) and runs the game as follows.
While we don’t hit game over we draw 3 shapes and iterate them. For each of them we call the method MakeAMove
If you wish to write an implementation you need to derive from IPlayer and implement this single method
This method should decide were to locate the shape and update the board with the location. The board is the one who is in charge to calculate and update the score.
Implement from scratch:
If you implement your own from scratch derive from IPlayer and implement MakeAMove
We can look at the game in a naïve way where at each move we look at one single shape (The first shape in deck) and decide where to place it. And a more complicated way where at each move we look at all 3 and decide what is the correct path for the 3 together.
All existing implementations containing the SingleStep key word are implementations taking the naïve way. The implementation FullEval is the only one taking the complicated and probably the better approach.
The FullEval runs recursive to calculate all possible paths where each path contains 3 steps and then it chooses the best path. But the method is designed to Make A move meaning one move, so it keeps the path in cache and will use it in the next steps of the same “3 shapes deck draw”.
If you derive from Existing implementations just need to override what you want to change. For example, I may derive from FullEval and override only the GatherStepsStats method if I think I have a better way to give a score for current step.
In a few places in code you can find lambda expression, LINQ and other syntactic sugar expressions.
public float ScoreGainNorm => ((float)(ScoreGain - 0)) / (127);
this is called expression-bodied member it creates a get property that return the assigned value.
var topScorePath =
from x in paths orderby x.ScoreGain descending, x.CellCount ascending, x.PlacementScore select x;
this sorts the dictionary in a similar way to a SQL query.
Good luck! would love to see your scores!
(By the way - Adi has a branch with a great implementation, if you are stuck you can check it out)