Here it is: The complete Lewis Carroll game in all its glory.
Final Milestones:
- Refactor Daisies
- Refactor Croquet
- Refactor Yarn
- Refactor Garden
- Refactor Chessboard
- Convert print to graphic in Garden
- Convert print to graphic in Daisies
- Write menu screen
- Add custom images, probably transitional screens
- Write transition between first two games
- Apply transition to other games
- Set moves in Chessboard
- Incorporate help dialogue
- Write end screen. Nothing so unambiguous as winning. There will be an imported image of a crown.
- Include restart option in end screen
- Have chess game play before end screen
-
[x] Isolate click function in menu
Over the course of the semester, I created several small games around a Lewis Carroll theme. I found that having a story to tell for a project gave it structure, and that allowed me to focus on execution instead of concept. For the final project, therefore, I elected to take that idea and run with it instead of creating something wholly new. My general plan was to take the four existing games and combine them into one multi-step one.
One of the appeals of this plan was that it let me delve deeper into the peculiar world of Wonderland Python that I had begun to develop. Each section had previously been a stand-alone game, designed to refer to the source material while still being entertaining on its own. My finished product does not, I suspect, make very much sense to someone unfamiliar with Alice in Wonderland and Through the Looking-Glass. However, any knowledge of the books (or other interpretations of them) will find the many references that much more pleasing. Like with the smaller projects, I enjoyed tying my decisions to the existing story; I was going for something of a surreal/nonsensical feel, and I hope that that came across. I made some choices with that goal particularly in mind. For example, the overall arc of the game is not the conventional one of levels that increase in difficulty. Instead, each section represents a chapter from the books, and they are set out in chronological order. Like Alice with her “Drink Me” bottles, players have no idea what a section involves until they plunge into them. Focusing on the interpretation of books that I love and know so well made the project much more enjoyable for me than it might have been if I had just been checking of milestones. It also allowed me to combine artistic and storytelling aspects with the technical parts, which I think is where coding and game design really shine.
The narrative was the fun part, but the coding itself definitely took the most work. One of the rather delightful parts of this project was that I got to go right back to the beginning of the semester. Here are the original versions of two sections, for the sake of comparison.
I wrote the first draft of the Daisies game in January and the Garden game not much later. I knew that I had learned a great deal this semester, but this really brought that home. We had done a refactoring exercise once, but it was a different experience to do it with all of my own code. It took a while, but I felt capable while doing it. Refactoring has the narrative aspect also, in that the structure already exists and you are just trying to execute it effectively. A lot of it was aesthetic (my garden and meadow look much nicer than they did the first time around) and a lot of it was putting in things like functions, things that I did not know about when I wrote the code originally but that make it far more efficient. One of the shining examples here was the chess game. I remember you telling me when I started it months ago that functions would make it much easier; it sat on the shelf for a while, but now I know what you meant. The refactored code for drawing the board and pieces uses nested functions as well as a custom class, and it’s perhaps a third the length of the original program (I don’t know what I’ll do with coding in the future, but I’m possessed with the desire to understand how to write a playable chess game – I can run a pre-set game with mine, but teaching it the legal moves must be very complicated indeed).
The refactoring took some time, but it was reasonably simple (there was just a lot to go through because the original code was so inefficient). The difficult part was tying the sections together. I knew that going into it, as I had had similar issues with the drawing and game apps (Croquet and Yarn, respectively); on those, writing the levels was an entirely different problem from orchestrating the transition. Having those projects actually helped me a lot in this one, as I could look back on what had worked and what hadn’t. One of the things that took me a long time with them was figuring out how to separate code between modules and still have it run properly. It was immensely frustrating then, but I went into the final project knowing how it worked and that saved me a great deal of trouble. That said, it was still the most complicated aspect of the program. If the game did not have the option to go back to the main menu and jump between sections at will, it would have been easier to put together. Instead, I went through several different iterations of which functions had to be where before figuring out what worked. Each game has its own module, but that does not allow it to call on the main menu function from the main module because then they would be referring back to each other (in which case Trinket gets very upset and refuses to play anymore). I ended up consolidating each game into a manageable set of functions drawn from the detailed code in its module. I then placed these consolidations in the main module, where I added the menu function to them so that one could go back to it from within the game. A particularly complicated bit stemmed from the fact that two of the sections (Croquet and Garden) don’t have a proper ending; instead, the player goes on until they are no longer entertaining. For those, I couldn’t just set the menu function to run when the game was finished. I wrote an onkey function that allowed the player to return to the menu at will. Ultimately, that turned out to be a good thing because I added it to all of the games. However, they couldn’t reuse the same one because each game has different turtles drawing and playing it, so there are four different end functions in the main module.
One of the attitudes that we talked about early the semester involved tunnel vision and remembering to take a step back. It’s always been a trap that I fall into; it is so easy to obsess over why a piece of code isn’t working the way you think it should instead of thinking about whether it is actually the best way to solve a problem. I ran into this several times on this project. One was with the use of the chess game. It wasn’t exactly a coding problem, but I struggled with translating the book into legal moves. At the beginning of Through the Looking-Glass, Lewis Carroll provides a chess problem (a board with some pieces set out and the goal to win in eleven moves). I couldn’t visualize it properly without setting up a real board, which I did. Ultimately, I figured out (with some help from similarly irritated people on the internet) that Carroll’s solution in no way follows the actual rules of the game. Each individual move is legal, but the order is every which way. The formatting of his solution gives it more coherence, but it becomes clear that you must follow his logic and not normal chess logic. Instead of red against white, the moves are ordered so that Alice alternates moves with the whole rest of the board. Looked at by conventional rules, this has white moving nine times in a row. There is also a ‘Queens castle’ instruction that is simply not a move that exists. I stared at my chessboard for some time trying to decide how to put this into my game. Eventually, I remembered that my goal was to stick as close to Carroll’s world as possible, so I bit my tongue and set my Python chess to follow the moves of his Looking-Glass chess. This is why the ending game makes no sense, but it is true to the source material so I’m actually all right with how it turned out.
Another attitude aspect that I’ve had trouble with is that I’m dreadful at doing something with no purpose. This came up in this game with the dictionary and especially with the external data file. These, as I’m sure you can tell, add nothing to the game; in fact, they make the code more complicated than it needs to be. I struggled with them in part because they were the least familiar concepts (so I can see the point of requiring their inclusion – I do understand them a little better now) but also in part because they felt like a waste of my time. It is part of the learning process, I suppose, but I look forward to doing projects that use things with a purpose.
This project ended up being an excellent conclusion to the course for me. The concept allowed me to go back over everything I had learned and rework it to the best of my abilities, showcasing how much those have improved. I have learned how to use milestones reasonably effectively (compare with the ones from the drawing app to see the full learning curve). The theme gave it focus, and my love for the source material kept me passionate about making it as good as possible. It’s a peculiar, idiosyncratic little game, and I’m not at all sure that it will make sense to anyone else, but I rather love it.