I’ve started my first C# project — with a peer reviewer / guide — and I’m feeling especially embarrassed over how challenging this simple exercise has been for me. I promised to be as transparent as possible, therefore this post explains the project, provides links to my code (in GitHub), and describes my thought process and feelings.
Introducing: The Project and Peer
My first C# project was proposed by one of my favorite people in San Diego: the esteemed Deborah Lee (for privacy, I’ll omit links to her profile(s) until she says it’s okay to do so). I met Deborah when she joined an Agile team I was coaching and I’m grateful to have her as my peer/guide (more on this later).
We’re starting a project that will surely change the world: a console application that plays Tic-Tac-Toe. Five year old children without mobile phones, iPads, or modern devices rejoice!!
I have no idea how to write a Tic-Tac-Toe game in C#. As an Agile practitioner, I’ve naturally started by attempting to break down the smallest slices of this “epic” into increments that do something and provide feedback on how to proceed next. My task breakdown, right now, looks like this:
- A console application that lets a single user play Tic-Tac-Toe with a computer opponent.
- Draw the “game grid” and save one move made by the user.
- The computer can make a move, allowing alternate turns by user and computer.
- The program can determine when a player has won.
- The computer makes an intelligent move (i.e., when it’s the computer’s turn, it tries to prevent the user from winning).
My Code for all to Ridicule
Gulp. Here’s where things get uncomfortable. To learn source control (and provide for ease of peer review), I have committed my project to GitHub. If you feel so inclined, I invite you to follow along through my trials and tribulations.
Be kind, please.
My Progress Thus Far
As of this posting, I have accomplished my first task to draw the game grid and allow a user to save a single move. This took me three increments to achieve and I’ll describe them according to my thought process:
Step One: Just make the damn thing work any way I can…
My first commit was perhaps the ugliest, most inefficient, linear block of code ever written. But damnit, it worked!
To create the game grid, I started with a string variable under the assumption that I could use a combination of newline statements (\n) and nine other string variables representing each space in the grid. Then, as each move is made, I just update the grid-variables with either an “X” or “O”, then print the string all over again!
Problem being, this requires a ton of repeated code. Everything becomes linear (easy for a novice to follow, though… it’s just like reading a book, right?). Inserting strings into strings feels like an array. It’s clearly terrible. I know from listening and watching developers, I should be creating methods for repeatable things.
“Screw it. It works. My first GitHub commit!”
Step Two: There’s gotta be a better way to maintain the game grid…
My second commit updates the program to use an array for storing the game grid and moves, leveraging a for loop to print each row before moving to a new line.
Here, I realized that I could easily print the array line-by-line by counting the array index at each position. When reaching the index that starts the second row of the Tic-Tac-Toe grid, stop and start a new line, etc. This also forced me to add code to loop through the array and update the contents with each move played.
It’s simpler! But the program was still linear and swapped one set of repeated code for another. I knew I needed to create a method for drawing and updating the grid, but I didn’t understand how to pass the array into a new method. Worse, my lesson in understanding “helper” methods from Bob Tabor’s online course emphasized that each method needed a “return” statement. What’s the syntax to create a helper array method? How the hell do I return the stupid array back to the main program?
“Screw it. It’s better. My second GitHub commit!”
Step Three: Deborah says, “DRY – don’t repeat yourself”. Figure it out…
My third commit is where I stand at the time this post was published. The changes update the program to use two new methods: one to draw the grid, the second to update the array.
I spent hours trying to figure out how I might pass the array into a new method and use a “return” statement, just like the tutorial video on helper methods. At one point, I thought to myself, “C# is even more prohibitive than PL1. I just want to write a damn function to run this stupid for-loop.” And so I tried something – I moved the declaration and initialization of the array above the main method and wrote a new method with “void” to run the for loop code.
Something worked. Excuse my French, but fuck yeah!
From there everything clicked. I wrote a second method to execute the update of the array by passing in user input and I deleted a ton of repeated code.
It felt good to commit the new version. I don’t know what more I could change, to be perfectly honest. I’m sure this version still sucks in the eyes of most programmers, but I’m at the point where I’m excited for peer review comments, rather than dreading them.
My Feelings Thus Far
When Deborah let me know that she’d partner with me on this project and suggested Tic-Tac-Toe, I was initially relieved and excited. Here’s a chance to work with a familiar person, one who I can trust has my learning at heart, and the opportunity to write a program I don’t have a clue how to do.
The act of decomposing the work into milestones and functional pieces also created sensations of relief. I was cutting into the complexity and reducing it. Sure, I still have no idea how I’m going to calculate when a game has been won, but I don’t need to worry about that right now. I can let things emerge and see what knowledge I gain that might provide insight when the time is right.
Writing the code has been an exercise in frustration and delight. Frustrating because I often feel like I’m exploring areas that I’m just not equipped to understand yet. There’s a difference between trial and error and fumbling around while lost in the dark (and likely to be eaten by a grue). Yet delightful when I figure something out, as part of learning involves those moments when you win and pat yourself on the back.
The most significant feeling I want to emphasize is that of fear, however. Despite the fact that I know Deborah personally and believe she would not scoff at my awful code (that first commit… ugh), I was still hesitant to show her. I didn’t want her to know how bad it was… and maybe I could hide it from her and wait to show something better.
For me, as an Agile coach, this highlights the importance of respect and safety in our teams (and organizations). If I’m scared to be vulnerable to someone I have a safe relationship with, I can only imagine how damaging a culture of perfection, seniority, and performance measurement must be.