Wednesday, April 21, 2004

Hey, this is cool!

Microsoft is making available (for free!) the same C++ compiler that ships with Visual Studio .NET 2003 Pro.  Now you can write apps that target the Windows platform and the CLR using the Visual C++ language.

Wednesday, April 21, 2004 3:38:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, April 18, 2004

As a family we have a hard time getting together each night to read scriptures.  This isn't to say that we don't remember to, it's the doing it that is the hard part.  It's great that the girls are so enthusiastic and desirous to read scriptures and hold Family Home Evening.

Tonight we sat down and started the book of Jacob in the Book of Mormon.  Anyah is such a great reader!  Leiel is doing a great job too of wanting to read and having Mommy or Daddy help.  After reading the first chapter we played a family game of Settlers of Catan (the girls love it!).  It's a good object lesson for them - especially Anyah who has a very hard time not winning all the time.  We're working on that.  Lisa ended up winning.  Anyah and Leiel were tied for second place.  I could see Anyah starting to pout when she discovered she lost but I quickly diverted her attention by having everyone give mom a high-five and that seemed to offer some good levity and she realized that not winning wasn't so bad.

I was very impressed with her and how she handled having the robber placed on her resource hexes - she laughed it off and played along.  Leiel also had a great time moving the robber when she rolled a 7.

Following the family game, we ate chocolate pudding - Addie was gobbling it up voraciously!  She sure is a cutie!

Well, I have to go to bed to get up early tomorrow!

Sunday, April 18, 2004 4:47:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

In writing my Settlers of Catan computer version, I came upon the following conundrum: how do I perform coordinate hit tests on a hexagonal grid?  Dealing with cartesian, square grid is very simple and well understood.  A hex grid, in reality is not very much more complex, but does throw a few curve balls (i.e. there are angles to consider, cells overlap, etc).  I did a little online research and my search wasn't too fruitful, but what I did find confirmed some ideas I already had which I'll outline here.

A few points of interest with respect to hex grids:

  • There are two ways of rendering the grid (flat-side up and point up).  Each of these presents a different algorithm and a solution to the point hit test problem.
  • If the flat-side-up orientation is chosen, you will actually end up with fewer hexes visible on the screen at a time.

Here is the scenario I ended up with:

  • I chose the point-up orientation of the hexes.
  • Each successive column/row of hexes overlaps by one pixel on its neighboring hex to provide a seamless edge - this greatly simplified the creating of hexagonal tiles.
  • My hex-grid (map) is rendered graphically offset from the upper-left corner of the image so we must take that offset into consideration during our hit test.

In solving the problem, I made the following assumptions and assertions on my code:

  • My hex tiles are a fixed size: 153 x 177 pixels
  • The origin (0, 0) of the map is offset to the upper right of (1, 0)
  • In order to provide graphical symmetry in my maps, every other row starting with 0 (continuing with 2, 4, 6, etc) has one fewer column than the odd rows (1, 3, 5, etc).
  • We have to take the 'missing' column as well as points that fall off of the grid into consideration while performing our hit test or we might return invalid coordinates.

Now to the solution:

In order to perform the hit test, I decided to treat the entire map in a traditional, grid-based manner, dissecting the map into a grid where each square was 153 x 133 (or MAPTILE_WIDTH x MAPTILE_HEIGHT * .75).  Each square then contains points that belong to up to three hexes.

If my y coordinate falls on an 'odd' row, then the lower 66% of the square belongs to two adjacent hexes.  The upper 1/3rd belongs to three hexes.  If the y coordinate falls on an 'even' row, the lower 2/3rds of the square belong entirely to a hex and the upper 1/3rd belongs to two other hexes as per the diagram.

The other issue to resolve is that of calculating points in relation to a given slope (very easy using the point-slope equations that I learned back in junior high-school).  If you observe the code you'll see that I cheat a little...I preresolve the slopes (since they are constant and I don't want to have to reevaluate a known value repetitively).

I'm not going to give a play-by-play of my code, but if you have any questions, feel free to let me know; I've commented that which I felt was important to comment and have included it below.

Just a few points of interest about my code because it does target my game and isn't entirely generic, though breaking it out to be completely generic would be a no-brainer, I don't have the immediate need to do so:

  • Map.Current is a singleton instance of a Map object (defined elsewhere) that represents the map in question.
  • Several of the constants that I use in the code are defined in a Constants class.
  • InvalidPoint is a point object (defined as private readonly Point InvalidPoint = new Point(-1, -1)) and represents any coordinate position on the map that doesn't correlate to a coordinate on the grid.

Undoubtedly, there are better algorithms for detecting hit tests against a hexagon and I'd love to see them...this merely represents a first-go at the problem and I think it addresses it well.  This function is intended to return a Point object containing the map x-y coordinate pair as resolved against a pixel x-y coordinate pair (e.g. from the current mouse position).

Ok, here's the code:

private Point getHex(Point pt) {
  
if ( null == Map.Current ) return InvalidPoint;

  
// precalculate the 'hotspot' regions
  
const float MAPTILE_HEIGHT_HOT = Constants.MAPTILE_HEIGHT * .75F;
  
const float MAPTILE_UPPERTHIRD = MAPTILE_HEIGHT_HOT * .33F;
  
const float ANGLE = 0.589F;
  
const float ANGLE2 = 1.8095F;
  
const int MAPTILE_LEFTHALF = Constants.MAPTILE_WIDTH >> 1;

  
// subdivide the map up into squares.
  
// each square contains 1/2 of two opposing hexes horizontally and a portion
   // of one or two hexes vertically
  
// for ease of calculation, offset the point by the map margins
  
pt.Offset(-MAP_MARGIN, -MAP_MARGIN);

  
int row = (int)( (pt.Y + ( pt.Y / MAPTILE_HEIGHT_HOT )) / MAPTILE_HEIGHT_HOT );
  
int col = (int)( (pt.X + ( pt.X / Constants.MAPTILE_WIDTH )) / Constants.MAPTILE_WIDTH );

  
// convert the point (mouse coord) to coordinates relative to the current square
  
pt.X -= ( col * Constants.MAPTILE_WIDTH ) - col;
  
pt.Y -= (int)( row * MAPTILE_HEIGHT_HOT ) - row;

  
if ( pt.Y < MAPTILE_UPPERTHIRD ) {
     
if ( row % 2 == 0 ) {
        
if ( pt.X < MAPTILE_LEFTHALF && pt.X * ANGLE > pt.Y )
           
row--;
        
else if ( pt.X >= MAPTILE_LEFTHALF && ( pt.X - MAPTILE_LEFTHALF ) / ANGLE2 < ( MAPTILE_UPPERTHIRD - pt.Y ) )
           
row--;
        
else if ( pt.X < MAPTILE_LEFTHALF )
           
col--;
     
}
     
else {
        
if ( pt.X >= MAPTILE_LEFTHALF && ( pt.X - MAPTILE_LEFTHALF ) * ANGLE > pt.Y )
           
row--;
        
else if ( pt.X < MAPTILE_LEFTHALF && ( pt.X / ANGLE2 < ( MAPTILE_UPPERTHIRD - pt.Y ) ) ) {
           
row--;
           
col--;
        
}
     
}
   }
  
else if ( row % 2 == 0 && pt.X < MAPTILE_LEFTHALF ) {
     
// if the point of interest is within the lower 2/3 of the hex, then there are
      // two possibilities - even rows (0, 2, 4, ...) contain 
two hexes, whereas odd
      //
rows (1, 3, 5, ...) have only one hex.
     
col--;
  
}

  
if ( col < 0 || row < 0 || row >= Map.Current.Rows || col >= ( ( row % 2 == 0 ) ? Map.Current.Columns - 1 : Map.Current.Columns ) || pt.X < 0 )
     
return InvalidPoint;
  
else
     
return new Point(col, row);
}

Sunday, April 18, 2004 11:26:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Thursday, April 15, 2004

Well, I had the opportunity to attend a Microsoft MSDN event today entitled “Writing Secure Code - Threat Defense”.  I went in with high hopes.  I must of course say that I wasn't entirely disappointed, but my expectations were not met.

Years ago (in a past life) I used to present at Tech Net and MSDN events (I'm starting to get back into it too - but that's another blog) so I have some insight into what a presenter goes through.

All in all, he did a fairly okay job but left out many ideas and concepts.  Ultimately I came away with a few things:

Valuable Resource: O'Reilly's book '.NET Security'

Perhaps the best, most useful information gained was concerning Code Access Security.  CAS is one of the most misunderstood aspects of .NET development and the presenter shed some light on the topic.  He illustrated the use of the .Demand() and .Assert() methods to control the stack walk as well as how to configure (briefly) an application to take advantage of CAS...that part was worth while.

 

Thursday, April 15, 2004 2:58:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, April 14, 2004

Hey, it finally feels like I made some progress!  I have never taken the time to really sit down and use the Xml objects built into the .NET framework.  It sounds asinine, I know, but honestly I have never had/found a need to use them.  I've used the DomDocument before in very limited ways in VB and Javascript, but never had broken down to use the .NET stuff.

Well, long story short, I got the ScenarioEditor utility to save and load my xml scenario files.  Plus they get validated on load against my schema file!  Hey, this is progress for me.  Previously, I would have saved the data to a binary file with my own proprietary data structure.  That would have been way to much for what I wanted to accomplish for such a small utility that didn't need such functionality.  I wanted scenarios to be creatable in tools such as Notepad.

I have yet to profile the code and go back over a few loose ends, but the utility is now in a functional state and ready to save scenarios for the game - that is goodness!  I'll get some screenshots posted shortly.

Wednesday, April 14, 2004 6:30:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, April 12, 2004

A good friend, Josh McCord, and I get together to code every Monday night.  It's been an on-going tradition now for a couple of years.  While I'd like to say we've made a lot of progress and released lots of code that would be misleading.  We've had aspirations of writing a MMORPG - in fact we made LOTS of headway towards that goal last year.  However, as many personal project go, the scope kept creeping up and expanding.  We tried to reign it in and have well-defined goals...alas, our efforts seemed in vain.  Eventually, we decided to put on hold all that we had been working on.  We have never intended to discard the code, mind you, but instead to leverage what we've done so far in new projects.  And we have been successful at bring forward the components that we developed for the MMORPG (such as a very cool networking infrastructure, as well as some general purpose utility classes and libraries) into our current game project.

We decided to tone back our efforts just a bit and write a multi-player computer game where the rules have already been defined for us.  We've had a tradition of playing Settlers of Catan for the last while and thoroughly enjoy the game so, why not?  We decided to create a computer version of the board game - especially after seeing what was already out and available on the Net.  Not to say anything particularly bad or negative about the already extant versions, but they sure need a lot of work.  Sure, the game mechanics are there, but presentation is a HUGE part of any would-be successful app and that seems to be an area in which they all suffer.

So far, we have the networking infrastructure (TCP/IP, sockets-based) already fully in place and implemented.  Additionally several game mechanics are operational along with about 80% of the graphics.  Today's focus was finalizing the Editor utility and getting real-time stats for in-game display.  The Editor utility allows us to generate graphically a Settlers of Catan scenario file (xml-based) that can be loaded into the game at runtime.  The tool is complete but for the actual 'save' process which I don't anticipate should be a big deal.  I have a feeling it will write itself.

Monday, April 12, 2004 8:07:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, April 10, 2004

I had the great opportunity last week to go down to Brigham Young University (BYU) to be a judge for the Imagine Cup 2004.

There were three teams that had to create some software that had to meet the following requirements:

  1. The app had to be written using .NET technologies (each team chose C# as the language of choice)
  2. The app had to run on a PocketPC (or rather, had to rely on the Compact Framework)
  3. The app had to utilize Web Services

Each application was judged on a variety of factors:

  • Innovation
  • Application Smarts“
  • Usefulness
  • and to a lesser degree, Style (though I deem that one of some import)

Each of the three teams came up with some pretty cool stuff.  The winning application was a 'reminder' app that would remind you of tasks or assignments based on location.  It used Web Services that the team wrote as well as the Microsoft Map Point Web Services.  While GPS-functionality had not yet been written into the program, it was the next logical step.  The goal was that, based off of your task list and current GPS information, your PocketPC would remind you of to-do items as you approached the 'hot spots'.

Pretty cool - especially if integration into Outlook were ever completed.

Good job guys and keep up the great work!

 

Saturday, April 10, 2004 4:46:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

A few years ago a fellow MS consultant (and very good friend of mine, Matt Smith) and I had the bright idea of starting a .NET users group here in the Salt Lake Valley.  Well, time has passed and the group has flourished.  I have the opportunity of serving as the President of the group.  This responsibility is daunting and requires a lot of time.  I have two great aides that help guide the group (Jason Walker - VP and Josh Crosby - secretary).

We meet every second Thursday of the month at Northface University at 6:00 pm.  We invite all to attend.

Please visit our site and drop by in you're in the neighborhood.

Saturday, April 10, 2004 4:33:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

Well, this marks it!  After much deliberation and wavering, I have finally decided to start blogging.  This post represents the first in hopefully a long line of posts on the Zupancic Perspective.  Allow me to introduce myself.  My name is Aaron Zupancic.  I am a native of Las Cruces, NM.  I am the oldest of six children.  Back in 1991 I graduated from Mayfield High School.  Shortly thereafter I took two years to serve a mission for The Church of Jesus Christ of Latter-day Saints in Mazatlan, Mexico.  In Jan 1992 (just months prior to my mission) I moved up to Salt Lake City, Utah with my father.  Since my early years I have had a stong inclination towards computers and the so called 'technical' realm.  This devotion has continued on to the present.  I have had the opportunity to be a trainer for several years.  How I love to teach!  Following that, a friend and former student of mine, Ryan Redmond hired me to a software developer for a small company called Avysta Software.  I functioned as a technical team lead and architect of a CRM (Customer Relationship Management) system that grew quickly and continues to thrive.  Soon thereafter my devotions fell to consulting.  I had the opportunity to offer my services as a Microsoft Consultant - what a thrill!  Microsoft is awesome, despite what some people may say (I might just blog about that one some day).  Currently, I am a consultant for Keane, Incorporated in Salt Lake City and am happy to be there, offering my services.

My hopes for this blog are high.  The primary reason for establishing it is to disseminate my discoveries, techniques, and insights into the world of software development.  There are other motives too, of course, but that is the main one.  I love software development and want to share what I know and learn with the greater community.

Hopefully this blog will be useful to those that use it and scour its pages.  Please feel free to provide comments and ideas.  I look forward to ongoing feedback and interaction.

Saturday, April 10, 2004 4:26:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback