Monday, August 24, 2015

TournamentCompare v0.002 - Enumerated Types in data first MVC

After tinkering with the controllers and views, I decided to look into a way to display the enumerated types used to set where the players were previously before this match. Ideally I wanted a radio control (as I had in Clarion), but the formatting eluded me for a super clean and simple implementation without losing data first design. In the end it turned out to be easier as a byte-stored enumerated type that can then be edited as a droplist.

Tournament Templates

One of the main parts of the program is to be able to put together any tournament format and then be able to run through thousands of tests to see the inherent bias of the tournament type. The tournament templates to be tested would then need to be anything from single elim, round robin, double elim, swiss, world cup rounds into single elim, etc. To achieve this, each tournament template would be a combination of TournamentTemplateMatches where each match accepts the 2 entering players from either the original player pool at the start of the tournament, another match previously held (Eg: single elim final match accepts the winners from the semifinals matches), a round robin subtournament, or an aggregator of previous scores to create a subtournament pool of ranked players.

Because each match could be pointing back to another match or another round (I'm assuming that subtournament aggregators can be handled by the round template with no rounds), I needed a concrete way of storing which type it was. Setting the PreviousType to "Match"would also mean that the PreviousMatchID is now valid, whereas if "Round"was the previous type then the PreviousRoundID would be valid.

Enumerated Types in data first MVC

Ideally I'd like to see in the database the type listed so that the data is a bit more human readable, but after investigation it seems that C# prefers integers or Bytes as the underlying enumerator value. I'd debated changing them to integers, but decided to use bytes instead (Tinyint in SQL) so that they appear as a different type in not to be confused with an ID. Changing the database wasn't too hard after manually changing the data to conform, then updating the field type in the designer.

Because I want to continually bring in database changes, I was keen to find a way that left the enumeration types already bound. I'd initially added the types in as another model, but found out later that you can add them directly into the model designer of the database with a right click > add >  enum  or by adding it to the enum types in the model browser. You can then change the fields to the new enumerated type. Doing this way it maintains the enum inside the database design (and scope) and also doesn't drop the assignment of the enum when the database is reloaded.



The display fields handled the enum perfectly, but the editing fields treated it like a string. There was some additional code to manually change the @html.EditorFor() to a @Html.EnumDropDownFor(), but I really wanted to be able to regenerate the controllers and views for any data first changes, so eventually settled on adding a html helper to overload the EditorFor() when an enum is detected.



Friday, August 21, 2015

TournamentCompare 0.001

I've been weighing up what programming project to work on for a while. I had Factor Friends as the front runner, but the move to a facebook friends variant didn't pan out as facebook now only allows access to friends of friends to only those who have installed / run your application. In some ways it is sad that the original concept cannot be done, but at least it wasn't made completely redundant if I had finished it before the changed the API.

On to TournamentCompare. I have been meaning to return to the Designing a Tournament series of articles for a while and it's really at the stage where I need some actual stats to pull together some comparisons. I had written a tournament analysis program back in 2006 to do some of the bias analysis, but since then I'd lost the Clarion development environment and couldn't continue modifying it for non-perfect play. So, a total rewrite is in order and hopefully make it web based and accessible for others to vet and build their own tournament types.

After a bit of digging it seems that another MVC application should be pretty easy, but use bootstrap to help with the presentation and graphs. Even though code first EF design seems to be more prevalent these days, I'm still a stickler for getting the data right so I've stuck with data first design.

Starting off the app in Visual Studio 2013 was pretty easy following this data first tutorial, although I'd created the MVC app first before creating the database. VS 2013 now has the ability to immediately add a SQL database right into the MVC project and create / modify tables and data right from within Visual Studio. I'm impressed! Within 1/2 hr I had the first TournamentTemplate tables done and looked like getting the others completed was just a matter of time. Went back to the tutorial to build up the entity framework for the starting tables, but unfortunately a VS crash took out the project connectors. Since it was so early I dumped and recreated the project with only the database making its way into the new project. EF done. Checked a quick update of the DB to make sure the EF would also update, and it looks pretty good so far.


Tuesday, August 18, 2015

Burnett Heads

Wednesday 12th August (1h) Northerly 20-30 Kn Nielson's
Wednesday looked good a couple of days out and it kept up to expectations. Wit the low tide at midday keeping Burnett Heads off the table, I went down to Neilson's to see what it was like. From the headland it was blowing LOTS. Scary lots. Talked it over with Wardy before deciding to give it a go anyway. As I was setting up there were a couple of windsurfers prepping to go out too, so that made me a little more confident. It was mostly over 20Kn (probably 25 average) and the extra wind made a world of difference to the fun that Neilson's had to offer. Boosted big off the first wave I hit and knew it was going to be a good session. 

2nd big boost I reached for the wave a little and went up into a backroll. I'd caught myself starting to loop the kite, but since I'd been watching some kiteloop transitions the night before I wasn't as afraid as before. I let the kite go and managed to come with a double backroll by the time I hit the water. Didn't ride away, but was fairly well controlled. So much wind that it still felt risky, so I left that one out for the rest of the session. 

The waves were bigger than yesterday as well as holding a better line from out the back to surf the swell line. Coming out from the shoreline pocket behind the rock wall was much easier to get up to speed and could pretty much hit most waves on the way out. I didn't want to be super fast anyway as the wind was still cranking. Big boosts everywhere. 

Finished the session with a mislanded boost that took the board under me and twisted my ankle a little. I could still walk when back on shore, but thought it was going to be bruised by the time the cold & adrenaline wore off. I had also hurt my hand from hitting a submerged rock and only found a big slice in my left pinkie after the end of the Burnett Heads session.    

Wednesday 12th August (1.5h) Northerly 20-30 Kn Burnett Heads. 
Met up with Wardy after 3pm down at Burnett heads to see if there were alternative launching points for low tide. Eventually decided to go back to the normal launching spot as the tide had come in enough to cover the mud. 

Really gusty on the tacks out to the wall. I'd trimmed right in for the walk to the water and had heaps of power on the water, but the lulls were almost dropping me in the water before the gust wrenched me up again. The kite was jellyfishing a little too so it might have needed a little more air. Eventually trimmed out to leave it 1/2 way and, although the gusts would pull me off track, the lulls were far more manageable and I didn't have to maneuver the kite as much. 

Approaching the wall and the flat water wasn't much more compensation for the gustiness, but the angle was good for boosting left. Wardy had mentioned that the wall provides an updraft, but my first boost still caught me by surprise. It was an average takeoff, but still went as high as I'd ever been! once you get about 2-3 metres off the water, the updraft catches the kite and just rockets you up. Most of my boosts were plugged landings as I struggled to work out what to do with the kite when you have so much time on the way down.

Most of the session was pure boosting and loved it. Still couldn't go all out and could easily get another couple of metres higher, but was high enough to scare me again. Landed a couple of backrolls, but one toward the end turned into a kiteloop with 1 & 1/2 rotations to have me landing on my back and being dragged downwind at 40Km/h. It was the biggest fall and almost ripped my helmet off. 

I was spent about 1/2 way through the session, but there really wasn't the right conditions for cruising so I mainly finished with casual boosts. After coming back in I realised that the camera wasn't on the helmet anymore. Wardy and I checked the beach in case it had floated in, but no luck. I went back in the morning to check the high tide line but it hadn't come in. Went down again at low tide to see if it visible on the mud flats where I had the stack. The mud was knee deep, but manageable with water over it, but I couldn't see a way to get closer to the location without bogging myself. Eventually called the loss and went home disappointed that I lost the footage of an epic day ....
    

Wednesday, August 12, 2015

Neilson's

Tuesday 11th August (1.5h) NNW 15-20Kn Neilson's Park.
Wednesday looked to be a good Northerly day, but the wind built up enough on Tuesday to have a go at Neilson's. It was blowing straight down the beach at Archie's with little to no waves, and possibly too low a tide for Burnett Heads. Turned out to be a nice little session and I'm glad I tried it so I know what to expect next time.

I thought the rock wall was a little bigger than it was, and it didn't really provide much clean water from the wind. Even though the beach was quite shallow there, I still couldn't quite turn and blast away out through the incoming surf. Most runs left me a little disappointed. I tried the bay to the north of the rock wall and, although it had a rocky bottom, it gave a lot better run up to the breaking waves.