In the building where I work at the University of Georgia, there is a fairly large map of Georgia hung on a wall in one of the hallways. I often find myself standing and staring in front of it. I do love maps and this one, with an edition date of 1967, is particularly well designed. It seems to strike the right balance of visual appeal and information. It shows all of the counties, cities, and even small communities not commonly found on your mobile phone's map app. I'm particularly fond of checking out all of the 159 counties. Only Texas has more counties than Georgia with 254. Some counties have some amusing names, such as the side-by-side counties of Bacon and Coffee (named after people, not the breakfast items). Some, if not outright controversial, at least raise an eyebrow or two to non-Georgians, such as Jeff Davis county, named after Jefferson Davis, the president of the confederacy during the American Civil War. Of course, quite a few Georgia counties are named after confederate leaders, but naming one after the confederate president seems a bit brash. But, the county was created in 1905 and the era of the Jim Crow south and the narrative of the South's "lost cause" (aka War for Southern Independence or War of Northern Aggression) was in full force. I originally thought the county was named after Davis because he was captured in Georgia after his and his cabinet's escape in 1865 from Richmond, Virginia, but apparently he never touched foot on the land that now occupies the county. (Davis was captured in Irwinville, Georgia.) Anyhow, it is an excellent map and I always enjoy studying it while taking a short break.
I sometimes wonder how well I would do if I were given a quiz on the location of each county. I can generally locate the general region of many of the counties - southwest, far east half way down, etc. - but I know I would fail miserably if 100% accuracy was required. The thought occurred to me that it would be interesting to design a simple game to teach the identification of the counties, but using general, not pinpoint accuracy as the score. And so this project was born.
Rather than focus on the counties of Georgia, I instead settled on USA's 48 contiguous states given that 48 is far fewer than 159 and I suspect learning the location of the "lower 48" would appeal to more people. My apologies to the citizens of the great states of Alaska and Hawaii, but no one seems to have a hard time finding them on a map of the USA, though unfortunately they are usually shown cut away from their natural geography and placed in the general area of northern Mexico. Talk about confusing 4th graders!
The Goal of the Game and How to Measure Success
The goal of the game is simply to locate a given state on a map. Besides being either right or wrong, the game tells you how far off you are in miles if you are wrong as measured from the center point of each state (more about that calculation later). It is this measure of how far off your guess is that I consider to be the most important measure of learning. I've even designed the game so that it chooses just a handful of states (5 is the default for now) for you to locate and the game only ends when you finally identify the location of each. If you are wrong, your score increases by the error mileage plus that state is put back into the queue for you to try again a little later. I keep track of the total number of tries as another measure of success. But, I would consider a low error mileage score with a high number of tries to be evidence of more learning than a high mileage score and a lower number of tries. The reason is that you are demonstrating good awareness of the nation's regions which I take is akin to good estimation skills. For example, knowing that Vermont is somewhere in the New England area and not out west somewhere is what the game is emphasizing.
Creating Helper Apps
Before I could work on the game itself, I needed to build the various elements the game would need to work. Here is a screen shot of a card in my stack that uses several helper apps for these tasks:
Of course, in the final version I will need to delete each state's abbreviation from the map. To create the game, I obviously needed to identify where each state was located on a map. How to do this? One way would be to create individual maps of each state and arrange them jigsaw puzzle-like to form the 48 as a whole. LiveCode has a very useful message handler - MouseWithin - that can detect if the mouse is currently located within the rectangular boundaries of an object. There are also ways to detect collisions between objects on the screen using the intersect function. However, I didn't want to have to create or find 48 separate images of states. I may come back to one of these options later if I'm motivated to refine the game, but for now I'm using a different strategy. I created a helper app to log the screen locations of the approximate center point of each state on a single USA map.
Thinking Ahead - What If I Need to Move the USA Map to a Different Location on the Screen
Yes, it occurred to me right at the start of the possibility that I would need to move the state map to a different location on the card. I almost never finalize the screen design until the very end of the project. So, logging the screen locations of each state would have to be redone if I moved the USA map. In anticipation of this, I used the center point of the image of the USA map as a calibration point. That is, when I logged the location of each state, I offset the raw screen location by the x and y coordinates of the map's center point. That way, I can move the map to any location on the screen later to line up each state's location perfectly. Here's the code for a button that does the logging:
1: on mouseup
2: wait until the mouseclick
3: put the location of image "USA with labels.png" into varLocationUSA
4: put (item 1 of the mouseloc - item 1 of varLocationUSA)&comma after field "coordinates"
5: put (item 2 of the mouseloc - item 2 of varLocationUSA)&comma after field "coordinates"
6: end mouseup
The image of the USA is titled "USA with labels.png." I put its current location (i.e., the x and y coordinates of its center) in the variable varLocationUSA. I then click on any state and the x and y screen locations of that state are logged by the mouseloc function. I then subtract the x and y coordinates of the map's center point. The resulting x and y of each state is then displayed in the field "coordinates." I then manually typed in the name of the state at the end. The result is a list of the state's coordinates aligned to the map's center point.
Did I Miss Any States?
I obviously had to do this logging of screen coordinates 48 times. In order to make sure I wasn't skipping any states along the way, I created another helper app that compared the names of states I had logged with a list of all 48 states. It then showed me the names of the missing states. Here is the code:
1: on mouseup
2: put empty into the field "missing states"
3: put the number of lines in field "all states" into L
4: put the number of lines in field "coordinates" into M
5:
6: repeat with i = 1 to L
7: put line i of field "all states" into varTarget
8: put false into varFoundState
9:
10: repeat with j = 1 to M
11: put item 3 of line j of field "coordinates" into varStatesDone
12: if varStatesDone = varTarget then
13: put true into varFoundState
14: exit repeat
15: end if
16: end repeat
17: if varFoundState is true then
18: next repeat
19: end if
20: put line i of field "all states"&return after field "missing states"
21: end repeat
22:
23: end mouseup
Besides the field "coordinates" already mentioned above, the field "all states" has just that, a list of all 48 states. The code compares each line in the field "all states" to the list of states already logged (item 3) in the field "coordinates" (the first two items are the coordinates). I set the variable varStateFound to false by default. If a match is found, varFoundState is set to true, which then triggers a new search with the next item in the field "all states." If no matches are found, varFoundState remains false and that state from the field "all states" is added to the field "missing states." This allowed me to plow through all of the states one-by-one as if I was on some magical car ride, checking now and then to see which states I've missed along the way.
Calculating the Distance Between Any Two States
The task of accurately calculating the distance between any two states is not easy, but it is straightforward. A good approach is to compile the GPS coordinates of the geographic center of each state, then create a distance matrix showing the distance between each state. I also learned about the Haversine formula, which takes into account the curvature of the earth. I decided this was a task perfectly suited for artificial intelligence, so I asked ChatGPT to create such a matrix. It did so, but in kilometers. Of course, despite the rest of the world, we in the USA compute these sorts of distances in miles. So, I asked ChatGPT to do it again, but in miles, and it did so without complaint. (Yes, when it comes to converting to the metric system, the USA is "miles and miles" behind the rest of the world. For some reason, we are fine measuring most soft drinks and wine in liters.)
I will need to figure out how to efficiently integrate this matrix in my game, but that is a task for the next version of the game.
Appendix
Here are three prompts I used in my conversation with ChatGPT to create the matrix of distances between the states (the first matrix it created was in kilometers):
Calculate a matrix containing the distance between the geographic center coordinates of all of the 48 continental united states using the Haversine formula.
Create a version of this matrix for exporting into Excel.
Create a new version of the matrix in miles that can export to Excel.
Next, I asked ChatGPT for some help with the coding:
Me: How do I import an excel spreadsheet into livecode.
ChatGPT:
answer file "Choose a CSV file:"if it is empty then exit to topput it into tFilePathput URL ("file:" & tFilePath) into tCSVData
Me: Show me an example of how I can find the value of a particular cell in the variable tCSVData and put that value into a variable.
ChatGPT:
put tCSVData into tData
put line 3 of tData into tLine
put item 2 of tLine into tCellValueanswer "The value in row 3, column 2 is:" && tCellValue
I then put all of this mileage data into a field on a separate card "mileage matrix" (I always prefer fields to variables in the development of a project because it allows me to actually see the data). I then added code that would read the state name from the first item in each identified row and the name of the state in the identified column, then put this information in the field "distance between states". This allowed me to verify that everything was working properly. Below is the code. I'll adapt and integrate this code into the next version of the game.
on mouseup
put field "mileage matrix" on card "mileage matrix" into varCSV
put field "dRow" into varRow
put field "dColumn" into varColumn
put line varRow of varCSV into tLine //row
put item varColumn of tLine into tCellValue //column
put item 1 of line varRow of varCSV into varState1
put item varColumn of line 1 of varCSV into varState2
put "The value in row "&varRow&", column "&varColumn&" is:" && tCellValue into line 1 of field
"distance between states"
put "This is the distance between these states: "&varState1&" and "&varState2 into line 2 of field
"distance between states"
end mouseup
Final Note: There is a new version of LiveCode that is AI-enhanced. I don't yet have access to this version of the application.