APIMASH and Intro to Game Dev Raleigh

I’m really excited to be hosting a few events in the Microsoft Raleigh office focused on Windows 8 development.  The first on revolves around our APIMASH starter kits – a great way to get started building mashup style applications in Windows 8, with templates and examples in both C# and HTML/JS.  The other sessions are intro to gaming, developing some simple games using Construct2, and GameMaker/other frameworks as time allows.   Here are the events/times: APIMASH: Tue 6/4/2013 from 10:00am to 2:00pm and Tue 6/11/2013 from 10:00am to 2:00pm Intro to Gaming: Wed 6/5/2013 from 10:00am to 2:00pm and Wed 6/11/2013 from 10:00am to 2:00pm Here’s a more official description of each event: Game Development for Beginners In this beginner level workshop we will cover the basics of game design, programming and publication. We will build a casual game and publish it to the Windows Store. This workshop is great for students, hobbyists and professional developers who want to learn the basics of game development and publish their first app to the store as no programming skills are required! Windows 8 App Mashup Series In this workshop you will learn how to develop Windows 8 apps based on well-known web service API's such as Twitter, Meetup, ESPN, EchoNest and data from the World Health Organization WHO. Your app could entertain or even change the world. This workshop is great for students, hobbyists and professional developers who want to learn the basics of app development and publish their first app to the store. For more info, stay tuned to the MSDN Events page!

Windows 8 “Elev8” App Challenge

We’re coming up on the annual Carolina Code Camp here in Charlotte and this year we thought it would fun to hold a hackathon leading up to the code camp, rather than simply run an all-day event at the code camp.  Here’s your chance to develop a great app for Windows 8, elev8 your skillset, and potentially win some cool stuff  Here are the details: The short version: develop a Windows 8 app, optionally attend some of our workshops, and submit it to the challenge.  At some point you need to be in person -- either at one of the workshops, or at the code camp -- as we need to prepare the demos and verify you are human.  Winners will be determined at the Carolina Code Camp.  The details: This app challenge is open to all Developers Guild members and members from the local community.  Download the free Visual Studio 2012 Express tools and other related SDKs here to begin developing your app.  Apps entered will be voted upon at the Carolina Code Camp on Saturday, May 4, 2013 by the attendees and organizers. While it is strongly encouraged you attend the Carolina Code Camp to demo your application, you do not need to be present to win (you will need to arrange to pick up your prize, if you win).  However, you must attend one of the Charlotte Windows App Developers workshops to demo and showcase your app prior to the code camp so we can have it loaded and ready for review. All apps must be original and new (published after 3/26) and must be submitted to the Windows store.  In the event it’s not approved yet and publically available, send some screenshots to show the app’s current progress.  The package files can be copied over to a demo machine, or you can bring your own machine the code camp to demo the application. Want some help developing your app?  Attend one of the Charlotte Windows App Developers meetups. Prizes: 1st Place:  Lenovo IdeaPad Yoga 11 and Nokia Lumia 820 Windows Phone.  2nd Place:  $250 Visa Gift Card, Wedge Mobile Keyboard and Wedge Touch Mouse. 3rd Place:  $250 Visa Gift Card As an additional incentive, the first 10 entries will receive a 4,000 XBOX Live Points card valued at $50! Also, don’t forget about the Keep The Cash offer from Microsoft.  Earn $100 for every qualified app you enter.  See site for more details.

Microsoft DevRadio: (Part 2) Using Windows Azure to Build Back-End Services for Windows 8 Apps

Abstract: Peter Laudati, Brian Hitney and Andrew Duthie are back for part 2 of their series and in today’s episode Andrew shows us how to deploy the OData Service for his Windows 8 app to Windows Azure as well as outlines the advantages and disadvantages to building back-end services via this approach. After watching this video, follow these next steps: Step #1 – Try Windows Azure: No cost. No obligation. 90-Day FREE trial. Step #2 – Download the Tools for Windows 8 App Development Step #3 – Start building your own Apps for Windows 8 Subscribe to our podcast via iTunes or RSS If you're interested in learning more about the products or solutions discussed in this episode, click on any of the below links for free, in-depth information: Register for our Windows Azure Hands-on Lab Online (HOLO) events today! Windows Azure Hands-on Labs Online Blogs: Brian Hitney’s blog Peter Laudati’s blog Andrew Duthie’s Blog Videos: Microsoft DevRadio: How to Get Started with Windows Azure Microsoft DevRadio: (Part 1) What is Windows Azure Web Sites? Microsoft DevRadio: (Part 2) Windows Azure Web Sites Explained Microsoft DevRadio: How to Integrate TFS Projects with Windows Azure Web Sites Virtual Labs: MSDN Virtual Labs: Windows Azure Download MP3 (Audio only) MP4 (iPod, Zune HD) High Quality MP4 (iPad, PC) Mid Quality MP4 (WP7, HTML5) High Quality WMV (PC, Xbox, MCE)

Skipping SSL Connections Locally

When developing locally, often times you don’t want to use SSL for a variety of reasons.  There’s no real point, since the request isn’t going over the wire.  Most of the time, connections are done via the loopback 127.0.0.1 address (although localhost can be used) which throws certificate errors.  This one problem is often easy to solve, but it relates to a bigger issue: dictating when (and when not) to use SSL on your site.  In the ol’ days, you wouldn’t want an entire site to be SSL for performance reasons.  Ideally, you want to gracefully redirect users to/from SSL based on the requirements of the page.  If a user navigates to a secure section like their account page, you’d like to use SSL.  If they navigate away to a page not needing SSL, you’d want to use http and not https.  There are a LOT of ways to do this, such as using MVC filters for MVC based applications.  One way I’ve solved this before was simply calling a method like so with each request: private void SetupSslIfNeeded() { //bail out on local connections – never need ssl if (Request.IsLocal) { return; } bool requiresSsl = false; string curPath = Request.Path; if (curPath.StartsWith("/account", StringComparison.OrdinalIgnoreCase) || curPath.StartsWith("/user", StringComparison.OrdinalIgnoreCase) || curPath.StartsWith("/admin", StringComparison.OrdinalIgnoreCase)) { requiresSsl = true; } //redirect to secure page if (requiresSsl && !Page.Request.IsSecureConnection) { string currentUrl = HttpContext.Current.Request.Url.ToString(); string newUrl = currentUrl.Replace("http://", "https://"); Response.Redirect(newUrl); } //redirect to non-secure page if (!requiresSsl && Page.Request.IsSecureConnection) { string currentUrl = HttpContext.Current.Request.Url.ToString(); string newUrl = currentUrl.Replace("https://", "http://"); Response.Redirect(newUrl); } } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } It’s a little more verbose than it needs to be, but it’s done to because there were a few port handling lines I left out for simplicity.  What this will do is avoid using SSL for local connections, and any page on the site except for those in the account, user, or admin folders.   The main downside of this approach is that it requires a redirect, which is a round trip to the server.  Ideally, you’d want your links to always be smart enough to know if they should go http:// or https://, but realistically, context switching between SSL and non-SSL pages is pretty rare so the client needing to endure the few extra milliseconds is an acceptable situation.  This is the way we currently handle SSL on http://www.rockpaperazure.com. 

Microsoft DevRadio: (Part 1) Using Windows Azure to Build Back-End Services for Windows 8 Apps

Abstract: Peter Laudati and Brian Hitney welcome fellow Developer Evangelist, Andrew Duthie to the show as they kick off their series on how to build back-end services for their Windows 8 apps using Windows Azure. Tune in for part 1 as Andrew gives an overview of the series and introduces some potential techniques you could incorporate as you build your back-end services. After watching this video, follow these next steps: Step #1 – Try Windows Azure: No cost. No obligation. 90-Day FREE trial. Step #2 – Download the Tools for Windows 8 App Development Step #3 – Start building your own Apps for Windows 8 Subscribe to our podcast via iTunes or RSS If you're interested in learning more about the products or solutions discussed in this episode, click on any of the below links for free, in-depth information: Register for our Windows Azure Hands-on Lab Online (HOLO) events today! Windows Azure Hands-on Labs Online Blogs: Brian Hitney’s blog Peter Laudati’s blog Andrew Duthie’s Blog Videos: Microsoft DevRadio: How to Get Started with Windows Azure Microsoft DevRadio: (Part 1) What is Windows Azure Web Sites? Microsoft DevRadio: (Part 2) Windows Azure Web Sites Explained Microsoft DevRadio: How to Integrate TFS Projects with Windows Azure Web Sites Virtual Labs: MSDN Virtual Labs: Windows Azure Download MP3 (Audio only) MP4 (iPod, Zune HD) High Quality MP4 (iPad, PC) Mid Quality MP4 (WP7, HTML5) High Quality WMV (PC, Xbox, MCE)

Win8 Apps: Check for Network Connectivity

A lot of apps require internet connectivity to function – like my app, Dark Skies.   One thing I overlooked when first releasing Dark Skies was a graceful check for network connectivity.  If the app launches and there is no connectivity, it should fail gracefully and notify the user.  Ideally, we should also plug into the Network Status Changed event handler, so our app is notified when the internet goes up or down during the app’s session. There are a couple of ways to accomplish this.  If you’re checking for internet connectivity occasionally, you can do something like this: public static bool IsNetworkAvailable() { try { ConnectionProfile profile = NetworkInformation.GetInternetConnectionProfile(); if (profile == null) { return false; } else { var networkAdapterInfo = profile.NetworkAdapter; if (networkAdapterInfo == null) { return false; } else { return true; } } } catch (Exception e) { #if DEBUG throw; #endif return false; } } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } If you’re checking for connectivity frequently, you’ll likely want to cache that result in a variable, and simply change the cached status when the network status changes.  Wiring up the event is pretty simple: NetworkInformation.NetworkStatusChanged += NetworkInformation_NetworkStatusChanged; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } And then the event handler can do whatever you’d like: private async void NetworkInformation_NetworkStatusChanged(object sender) { // ... } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } When the app loads, we’ll display a notification of some kind that internet connectivity is required:  Because the nature of tablets and internet connectivity, the state of the connection may change frequently.  Having a simple way to check for network connectivity and handling changes to the network status is a great way to ensure a smooth user experience! Oh – it’s also a good idea to check before doing anything that might throw a network-based exception.  For example, on app load, I made the mistake of always acquiring a push notification channel: await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } If the network is unavailable, this will throw an exception.  So, be sure to check for network connectivity and/or handle exceptions when setting up push notifications: private async void AcquirePushChannel() { try { if (IsNetworkAvailable()) { CurrentChannel = await PushNotificationChannelManager. CreatePushNotificationChannelForApplicationAsync(); } } catch (Exception ex) { #if DEBUG throw; #endif } }

Scrubbing UserId in Windows Azure Mobile Services

First, many thanks to Chris Risner for the assistance on this solution!   Chris is part of the corp DPE team and has does an extensive amount of work with Windows Azure Mobile Services (WAMS) – including this session at //build, which was a great resource for getting started. If you go through the demo of getting started with WAMS building a TodoList, the idea is that the data in the todo list is locked down to each user.   One of the nice things about WAMS is that it’s easy to enforce this via server side javascript … for example, to ensure only the current user’s rows are returned, the following read script can be used that enforces the rows returned only belong to the current user: function read(query, user, request) { query.where({ userId: user.userId }); request.execute(); } If we crack open the database, we’ll see that the userId is an identifier, like the below for a Microsoft Account: MicrosoftAccount:0123456789abcd When the app connects to WAMS, the data returned includes the userId … for example, if we look at the JSON in fiddler: The app never displays this information, and it is requested over SSL, but it’s an important consideration and here’s why.   What if we have semi-public data?   In the next version of Dark Skies, I allow users to pin favorite spots on the map.  The user has the option to make those points public or keep them private … for example, maybe they pin a great location for stargazing and want to share it with the world: … Or, maybe the user pins their home locations or a private farm they have permission to use, where it might be inappropriate to show publically. Now here comes the issue:  if a location is shared publically, that userId is included in the JSON results.  Let’s say I launch the app and see 10 public pins.  If I view the JSON in fiddler, I’ll see the userId for each one of those public pins – for example: Now, the userId contains no personally identifiable information.   Is this a big deal, then?   It’s not like it is the user’s name or address, and it would only be included in spots the user is sharing publically anyway. But, if a hacker ever finds a way to map a userId back to a specific person, this is a security issue.  Even my app doesn’t know who the users really are, it just knows the identifier.  Still, I think from a best practice/threat modeling perspective, if we can scrub that data, we should.  Note: this issue doesn’t exist with the todo list example, because the user only, and ever, sees their own data. Ideally, what we’d like to do is return the userId if it’s the current user’s userId.  If the point belongs to another user, we should scrub that from the result set.   To do this via a read script in WAMS, we could do something like: function read(query, user, request) { request.execute( { success: function(results) { //scrub user token if (results.length > 0) { for (var i=0; i< results.length; i++) { if (results[i].UserId != user.userId) { results[i].UserId = 'scrubbeduser'; } } } request.respond(); } }); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }If we look at the results in fiddler, we’ll see that I’ll get my userId for any of my points, but the userId is scrubbed if it’s another user’s points that are shared publically: [Note: these locations are random spots on the map for testing.] Doing this is a good practice.  The database of course has the correct info, but the data for public points is guaranteed to be anonymous should a vulnerability ever present itself.   The downside of this approach is the extra overhead as we’re iterating the results – but, this is fairly minor given the relatively small amounts of data. Technical point:  In my database and classes, I use Pascal case (as a matter of preference), as you can see in the above fiddler captures, such as UserId.   In the todo example and in the javascript variables, objects are conventionally camel case.   So, if you’re using any code here, just be aware that case does matter in situations like this: if (results[i].UserId != user.userId) // watch casing! .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Be sure they match your convention.   Since Pascal case is the standard for properties in C#, and camel case is the standard in javascript, properties in .NET can be decorated with the datamember attribute to make them consistent in both locations – something I, just as a matter of preference, prefer not to do: [DataMember(Name = "userId")] public string UserId { get; set; }

Windows 8 DevCamp Charlotte 10/12!

Don’t forget – we have our weekly Windows 8 DevCamp in Charlotte tomorrow, 10/12! In this week's DevCamp, we'll dive into Sharing, Settings, and Roaming. We will also cover some tips and tricks for developing Windows 8 applications using HTML, JavaScript, and CSS. Finally, we'll also spend a few hours going hands on to ensure the best experience for your app! For more information and to register, visit http://developersguild.org/.

Windows 8 Event Resources

Here are some resources for the Windows 8 Events we’re doing in Raleigh & Charlotte: Slides and Cookbook App:  https://bthtemp.blob.core.windows.net/misc/Win8-devcamp.zip Contoso Labs: http://www.microsoft.com/en-us/download/details.aspx?id=34619 Badges/Glyphs: http://code.msdn.microsoft.com/windowsapps/App-tiles-and-badges-sample-5fc49148/view/SourceCode What happened to “Metro”?!   They’re now “Windows Store Apps” … Looking to manage and view Windows Azure storage accounts?  Check out Windows Azure Storage Explorer Creating an IIS server to use with WNS Push Notifications and Windows Store apps. Fiddler (HTTP Debugger).

Coding for Kids #3. Bugs!

In the first post, we introduced the problem.  We’re writing a program that solves the problem of finding 100 point words, where each letter in the word corresponds to its position in the alphabet (A=1, B=2, Z=26).  In the second post, we coded the basic solution that allows the user to enter a word, and we calculate the result. We have a bug, though, because we made the assumption that the letters passed in are lower case.  The word “automated” is a 100 point word, but “Automated” is displaying only 99 points, because the first “A” in the word isn’t getting recognized correctly.  Remember, in computer programming, we need to be precise. There are a couple of ways to solve this.  The first way will be to simply tack on extra if statements to deal with capital letters, like so: if (c == 'a') return 1; if (c == 'A') return 1; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }But, we already decided this function isn’t all that efficient, and this doubles the number of if statements.  Fortunately, C#, and more specifically, the .NET Runtime that hosts the application, has a rich set of functionality in the base class libraries (that is, what’s “in the box”) that can do some typical work for us.   In this case, the string object contains a number of useful methods to convert the entire string to either upper or lower case characters. For example, we can modify the getWordValue function to something like this: 1: private int getWordValue(string theWord) 2: { 3: int wordValue = 0; 4:   5: foreach (char c in theWord.ToLower()) 6: { 7: wordValue += getCharacterValue(c); 8: } 9:   10: return wordValue; 11: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Notice on line 5, we’re calling ToLower() on theWord, which converts the entire word to lower case characters.  If we rerun the application (F5) and try the word “automated” with a mix of characters, we’ll see we get the correct value: Even though we fixed the bug, our code is fragile.  What that means is that there are assumptions about the code that, if not corrected, will cause errors or unexpected behavior down the road.  For example, the getCharacterValue function still assumes the character is lower case, even though getWordValue anticipates that.  Sometimes, and especially in small projects, you just accept that the code is not ideal and move on.  Before we move on to reading files and finding 100 point words, let’s solve a couple of problems here in the code.   The first thing to understand is that computers store all data as 0’s and 1’s … called binary.  Each binary digit is called a bit, and 8 of those are called a byte.  The way computers translate those zeros and ones into a letter and words is through encoding.   Encoding is a standardized way to convert a binary number into a character.   Going through the ins and outs of encoding is worthy of a number of blog posts, but think of it like a map.  The computer sees a binary number like 01100001 – which happens to equal 97 decimal.   The computer has a character map that says the number 97 is equal to the letter ‘a’ (specifically the lower case ‘a’).   Without a character map, the computer has no way of knowing this is supposed to be an ‘a’.   As you might guess, the character map says the number 98 is equal to ‘b’, and so on, where ‘z’ is 122.   And while we’re at it, that character map also says ‘A’ (upper case) is 65, and ‘Z’ is 90.   These numbers have roots in a character encoding set known as ASCII, and it was convenient because all western characters could be represented in a single byte (more specifically, it could really be done with only 7 bits).  Today, it’s common for applications, and our runtime, to use Unicode – a more modern way to map the binary data to characters using extensible code points.  By extensible, it’s possible for Unicode to have code points that encompass virtually any number of languages. The point of the above, though, is that for English use, Unicode maintains compatibility with ASCII.  So, we can rely on those character numbers (65-90 for upper, and 97-122 for lower case) to tell us if we have an upper or lower case number.   Computers can process numbers _real_ fast, so instead of doing an evaluation of the character as we have been, let’s evaluate the number instead: 1: /// <summary> 2: /// Returns the value of a given character, where the 3: /// value is determined by its location in the alphabet. 4: /// (A or a = 1, B or b = 2, etc.). Case insensitive. 5: /// </summary> 6: /// <param name="c">The character to be evaluated.</param> 7: /// <returns>The numerical value of the character, 1-26.</returns> 8: private int getCharacterValue(char c) 9: { 10: //get the numerical/ASCII value of the letter 11: int charValue = (int)c; 12:   13: //if the character is an lower case letter a-z 14: if (charValue >= 97 && charValue <= 122) 15: { 16: return charValue - 96; 17: } 18:   19: //if the character is an UPPER case letter A-Z 20: if (charValue >= 65 && charValue <= 90) 21: { 22: return charValue - 64; 23: } 24:   25: //not an A-Z or a-z character, return 0 26: return 0; 27: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } The first thing we’re doing on line 10 is creating a local variable, charValue, to hold the numerical value of the character, c, passed in.  (int)c is called a cast.   We know we have a character, but we want it represented as a number.  The cast allows us to do that.   We cast it to a variable (charValue) because it reads clearer and is more efficient than casting a char potentially many times over.  A word of warning:  you need to know what you’re doing when you cast.   It’s safe to cast a character as an int to get the numerical value, but when getting into more complicated scenarios, failed casts raise an exception which need to be handled (and exception handling outside the scope of this series).   In general, I wouldn’t recommend working with character values directly unless you really were sure of what is going on encoding-wise.  This is a good example of it being okay, because we have very specific rules and expectations, and the app is overall quite simple. Our if statements on line 14 and 20 look to see if the character’s numerical value falls in the given range.  The double ampersand (&&) is a logical AND operation so both conditions must be true for the if to evaluate to true.   If it’s a lower case letter, we simply return that value minus 96, which will give us a number of 1 to 26.   Same for the upper case, although we subtract 64 to get its value.  The code above is more concise, runs FAR faster (though, is _still_ not the best if can be), but it’s not quite as readable or obvious as to what it’s doing.  That’s where effective commenting comes in.  Notice, too, we solved the upper/lower case issue in a far better way – it’s not as fragile.   We do lose some flexibility, however – if the “game” changes and makes vowels worth double, for example, we’d have to go back to something else.  Also, notice we check for lower case characters first.  This is deliberate:  while it will handle either lower or upper case, if the characters passed in are more often than not lower case, we return the value and it’s one less if block that gets evaluated.   For the purposes of our program, it’s not significant except as an academic exercise in code optimization.  For now, we’ll call this “good enough” and move on to the next challenge:  finding words!

My Apps

Dark Skies Astrophotography Journal Vol 1 Explore The Moon
Mars Explorer Moons of Jupiter Messier Object Explorer
Brew Finder Earthquake Explorer Venus Explorer  

My Worldmap

Month List