As I was playing with the initial prototype I had a flashback to circa 1983, appropriate given the 1980s inspiration for this game, namely Estimation Baseball, which I created at about the same time as I explained in my previous post. Back then, one of the major publishers of educational software was Plato. Jerry Morris, the principal of the school where I was teaching (Bluewater Elementary School in Bluewater, New Mexico) had purchased a variety of educational software titles for our school's five Apple II+ computers, including several titles published by Plato. During my flashback I recalled playing a clever math race car game for a single player. The game began with having the player take a "trial lap." I don't recall all the details, but basically the computer kept track of how long it took you to complete the lap while answering math problems correctly. Then, the race began with your race car pitted against a race car "driven" by the computer. The clever part is that the computer's car used the player's time during the trial lap. So, you were already being pushed to improve on your own ability. If you won the race, that new time was then used by the computer's race car in the next race.
Design Changes
This flashback motivated me to make two major changes to the design of my race car game.
First, instead of this being a game for two players, it is now a single player game. I've incorporated the idea of the computer's race car being driven by the player's best time.
The second major design change is to move away from the three estimation thresholds that were inspired by the estimation baseball game to indicate an estimation that was close enough for a single, double, triple, or home run. Instead, I just use the accuracy of the estimation, again measured as a percent of the correct answer, to move the car. So, even if the estimation was way off, say only 1% of the correct answer (e.g., an estimate of 10 for the correct answer of 1000), your race car would move just a tiny bit. The farthest the car will go if answered perfectly is half as long as the race track. The race was won, of course, when one of the race cars crossed the finish line, but a variable also kept track of the number of laps (i.e., tries) it took to get there. The computer's race car would move according to the lowest (best) number of tries taken so far in the same increments.
Video Demonstration of This Second Prototype
Here is a short video demonstration of the current prototype of the game:
In this video, the player completes a total of four races. The first race is the trial lap, so the computer's race car does not move. Notice that it took the player 5 laps (aka tries) to complete the race. The data from the trial lap is then transferred into the field "best try" (labeled as "best so far" on the screen). (Programming note: These fields, obviously, will not be displayed when the game is finished. They are shown to help me program the game. At some point, I'll probably use variables instead of fields to keep track of this data.)
On the second race, the player took 4 laps to complete the race. The computer's race car mimics the number of laps and estimations of the player's trial lap, which was 5 laps. The player wins the race.
On the third race, the player didn't do so well. After four laps, the player had not yet reached the finish line. But, the computer's race car finished the race in four laps - again mimicking the performance of the player during the second race.
For the fourth race, notice that the data in the field "best try," doesn't change. That's because the player's best try so far was in race two. For this fourth race, the player's performance improved and only needed three laps to finish the race. The computer's race car - again mimicking the performance of the player during the third race - would have needed another lap. So, the player won the fourth race.
Analyzing the Code
Just like in version 1.0 of the game, the most important code is in the button "Next Lap:"
1: global varCar1x, varCar2x, varNum1range, varNum2range, varNum1, varNum2, varLap1, varLap2, varLap3
2: global varDistance1, varCar2Lap
3:
4: on mouseup
5:
6: //reset fields
7: put empty into field "num1 field"
8: put empty into field "num2 field"
9: put empty into field "answer field"
10: put empty into field "percent field"
11: put empty into field "display answer"
12:
13: //This will determine how fast car2 will get to the finish line
14: put the number of lines in field "best try" into varCar2Tries
15:
16: //put random(varNum1range) into varNum1 - I'll activate this after all testing is done
17: //put random(varNum2range) into varNum2 - I'll activate this after all testing is done
18: put 10 into varNum1 //I'll delete this and next line after all testing is done
19: put 10 into varNum2
20:
21: put varNum1 into field "num1 field"
22: put varNum2 into field "num2 field"
23:
24: put varNum1 * varNum2 into varAnswer
25: Ask "what is the answer?"
26: put it into varResponse
27: put varAnswer into field "display answer"
28: put varResponse into field "answer field"
29:
30: //compute absolute percentage of correct answer
31: put abs(varAnswer-varResponse) into varDistance
32: put varAnswer-varDistance into varDistance2
33: put round((varDistance2/varAnswer),2) into varPercent
34: put varPercent into field "percent field"
35:
36: put 50 into varDistance1 //Note: This variable is actually initialized in the card script; I put it here temporarily during testing.
37:
38: //Move the player's race car a distance that depends on the accuracy of the player's guess
39: put (varDistance1*varPercent)+varCar1x into varCar1x
40: if varCar1x >= 100 then put 101 into varCar1x //This keeps the car from going far to the right after crossing the finish line.
41: //From version 0.1 - I may revert back these, so I'm keeping them for now
42: //if varPercent>=.95 then put varLap1+varCar1x into varCar1x
43: //if varPercent>=.80 and varPercent<.95 then put varLap2+varCar1x into varCar1x
44: //if varPercent>=.75 and varPercent<.80 then put varLap3+varCar1x into varCar1x
45:
46: //move the race car
47: set the moveSpeed to 200
48: move button "car1" to ((varCar1x*8)+100),70 // in 2 seconds without waiting
49:
50: //move the second race car
51: if field "best try" is not empty then
52: add 1 to varCar2Lap //Note: This is initialized to 1 in the card script
53: put item 1 of line varCar2Lap of field "best try" into varPercent2
54: put (varPercent2)+varCar2x into varCar2x
55: move button "car2" to ((varCar2x*8)+100),160// in 2 seconds
56: end if
57:
58: //show the key data to help with troubleshooting (to be deleted later)
59: put (varDistance1*varPercent)&comma&varCar1x&comma&location of button "car1"&return after field "data"
60:
61: If varCar1x>=100 then
62: if field "best try" is empty then wait 2 seconds
63: answer "You win!"
64: move button "car1" to 1110,70 in 1 second
65: if field "best try" is empty then
66: put field "data" into field "best try"
67: end if
68: if the number of lines in field "data" < the number of lines in field "best try" then
69: put field "data" into field "best try"
70: end if
71: opencard
72: end if
73:
74: If varCar2x>=100 then
75: answer "Sorry, you lost this race! Try again."
76: opencard
77: end if
78:
79: end mouseup
The code is clearly just an updated version of the code from version 1.0, so I'll only go over some of the key changes.
First, lines 30-34 take the player's answer to the math question and determines the accuracy of the answer as a percent.
In line 36 the variable varDistance1 is used to set the maximum distance the race will travel. That is, if the answer is exactly correct, the car will only go half (i.e., 50) the length of the race car track. I can easily change this as needed after getting feedback from the game play.
Line 39 computes the distance the player's race car will go.
Lines 46-48 move the player's race car. You'll notice that I've commented out the modifier "in 2 seconds without waiting" in line 48. This was how I moved the race car in version 1. Instead, I now move the race car according to the "speed limit" denoted in line 47.
Lines 50-56 move the computer's racing car using either the player's time for the trial lap or the player's best time. Line 51 is used to determine if the player just completed the trial lap. If it's empty, then they have not completed the trial lap yet. If it is not empty, they have. So, if field "best try" is empty, then the computer's race car does not move. Recall from version 1 that I had been keeping track of the player's race results in the field "data" (labeled as "testing data" on the screen). When the player completes the trial lap, the data from the trial lap is automatically transferred into the field "best try" because, obviously, the player's only lap is their best time .... so far. This all happens in lines 61-72.
Line 61 checks to see if the player has crossed the finish line yet: Is the position of car1 (defined as the car's "nose") equal or greater than 100? If not, then the rest of the code is skipped and the player has to press the "Next Lap" button for the next lap. If the player has crossed the finish line, then line 65 checks to see if the field "best try" is empty. If it is, then the player just completed the trial and the race data is transferred from the field "data" to the field "best try." If this is not the trial lap, line 68 checks to see if the number of lines in field "data" is less than the number of lines in field "best try." If it is, then the player outscored their best time and their new data is now the "best time" data and it is transferred to field "best try," replacing the data that was there previously.
Notice that the opencard command is triggered in line 71 if the race is over. This resets both race cars back to their starting positions and re-initializes a bunch of variables.
Lines 74-77 are only triggered if the computer's race car crosses the finish line before the player's race car. In this case, the player loses that race and again the opencard command is triggered, this time with line 76. The player is now challenged to try a little harder in the next race.
Questions about the Game Play
As this point, I'm uncertain if the game play will be fun using this strategy of number of laps needing to win any single race. Currently, I have it set so that the player wins if there is a tie. That is, if both the player and the computer takes the same number of tries (i.e., laps) to cross the finish line, then the player wins. If the math problems are difficult, it will be virtually impossible to obtain exact answers. So, depending on the difficulty of the math problems, I really don't know how many laps it will take to win a race. Only feedback from game play will determine this.
Some ideas I have now include automatically increasing or decreasing the challenge of the game as the game play warrants. For example, if the player set a personal best score by accident, such as by coincidentally getting the exact or almost the the exact answer several times in a row, they may never be able to repeat this performance and beat this time. I could add an algorithm that checks to see how many times the player has either won or lost in a row, then adjust the game difficulty after a certain number of wins or losses has been encountered.
I'm also not sure if the animation is appropriate for interesting game play. As you saw in the video demonstration, first the player's race car moves, then the computer's race car moves. I had played around with both cars moving simultaneously, but this sometime led the computer's race car finishing before the player's race car with the same number of laps. Although the animation felt right, I would have to change the design of the game away from using the total number of laps to determine the winner of a race. But, that might be what I need to so. So, I may revert back to this strategy at some point.
I'm also not sure of the right language to use in the game. So far, I've been using the word "lap" to mean try. I don't know much about racing, but each try doesn't seem like a lap to me. I also referred to the first race as the trial lap, so that's an obvious contradiction. I need to work on this.
Next Steps
Not surprisingly, there are an assortment of design changes that I need to do. Here are a few of the most pressing.
The Need for a Timer
Something that is obviously missing from the game is a timer for each math question. Recall that the educational value of this game is to learn how to make good, quick estimations. If the player has unlimited time for each math problem, then of course they can just work out the correct answer. Instead, the player needs to be pushed to come up with an estimation as quickly as they can. In the original game of Estimation Baseball, I think I gave the player about 9-12 seconds to enter an answer, with 3-4 seconds for each "strike." The amount of time given to the player is an important design decision. It can also be something that varies throughout the game. More or less time could be given depending on how well the player is doing.
Review the Future of the "Next Lap" Button
I need to consider if I should continue to let the player decide when the next race will start, or make it automatic, but with the option to pause the race. I see value in both approaches.
Improve the Graphic Design and Add Sound Effects
Right now, it's obvious to me which race car I drive and which race car the computer drives, but I doubt it would be so obvious to anyone else playing the game. I need to design the game to not only make this clear, but also to add some excitement by having the player choose and name their race car.
If you watched the video above, you probably were expecting lots of race car sound effects, such as the "vroom, vroom" of the race car engines being throttled. Sorry for your disappointment! But, I realize there are so many ways for appropriate sound effects to really enhance the game play.
Review and Enhance the Game Play
As already mentioned above, I need to seriously consider how to optimize the game play of this game. I need to fully capitalize on the race car metaphor here. Beyond the sound effects already mentioned, I can envision a grandstand of spectators who cheer and applaud when a race is won, or who voice disappointment when a race is lost. These are tricky design decisions. I don't ever want to do anything other challenge and engage the player. A close race that ends in defeat can be a very motivating event to try to do better. But, constantly losing can be a recipe for a failed game. I remember well how the Plato software challenged me to keep playing - and to keep doing mathematics. Even though the Plato software was meant for elementary school students, I remember enjoying the challenge of the game even as an adult. That's something special that I hope to recreate in this game.
No comments:
Post a Comment