You too can learn how to code
Almost anyone can learn how to program a computer, or, as it’s more fashionable to call it now, “coding.” You too can learn how to “code,” and I intend to show you that by getting you started on a simple Tic-Tac-Toe game.
Not that there is any shortage of “you too can learn how to code” articles here on Medium, though such articles generally focus more on the author’s own life journey and rarely say anything about a specific programming project.
I will cover a little bit of my journey up to this point before diving into the Tic-Tac-Toe project. I started learning programming in my teen years. I read Problem Solving and Structured Programming in Pascal by Elliott B. Koffman front to back when I didn’t have a computer equipped with the Pascal programming language, or any computer at all.
In high school, I discovered that IBM-compatible PCs came with Microsoft QBasic. I copied a GW-Basic program for drawing fractals from a book, and made a couple of optimizations in the process of adapting it for QBasic.
I also wrote a sort-of scroller video game, in which a spaceship must navigate an asteroid field without getting shot at by the enemy ships. It was primitive compared to the video games available at the time, but for not having my own computer, it was something to be proud of.

There are several criticisms of BASIC, the Beginner’s All-purpose Symbolic Instruction Code, but it does what it set out to do: provide beginners with a simple programming language that can be used for many different purposes.
Later on, as a college student, I had access to Microsoft Visual Studio 6.0, with which I could write programs in Visual Basic and Visual C++.
I did write simple DOS programs in C++, and thought about writing Windows programs. But since I still did not have my own computer, the amount of time I would have to spend in the school’s computer labs seemed prohibitive.
It wasn’t until 2013 that I bought my own computer. It was on sale at Best Buy, and the blue shirts tried to persuade me to buy a more expensive computer. At the time, I figured Visual Studio would cost at least twice as much as my computer.
All throughout that time, I read books about Java and C#, but I was unaware that professional grade integrated development environments (IDEs) for Java were available for no cost other than the time and energy it takes your computer to download the installer.
In 2017, I learned about NetBeans, and downloaded and installed version 8.2 on my computer. Eclipse and IntelliJ (Community Edition) are also available.
BASIC is no longer as widely available as it once was. JavaScript is far more ubiquitous now. If you’re reading this on a modern Web browser like Google Chrome or Mozilla Firefox, you have access to JavaScript.
Some of you might remember VBScript, which was available on Microsoft Internet Explorer as an alternative to JavaScript. VBScript was based on Microsoft Visual Basic, a professional programming language that is still used by a few .NET developers resisting the switch to C#.
Don’t think that JavaScript is to Java what VBScript is to Visual Basic, it’s not. Aside from the superficial similarities to Java, and Sun Microsystems allowing the licensing of the “Java” name, JavaScript is a very different animal from Java, very loose and sloppy.
Except for its ready availability, JavaScript is profoundly unsuited for beginners. For one thing, JavaScript developed very haphazardly. It was not at first meant to be object oriented or functional, now it’s both (though with caveats).
Also, to learn JavaScript, you also pretty much also have to learn HTML and CSS, since, despite the existence of Node.js, JavaScript is still pretty much bound up with Web pages.
The Hyper Text Markup Language (HTML) is not a programming language, but, like the name says, a markup language. To turn a text document into a hypertext document, you mark it up with tags to indicate which pieces of text are headings, which are links, which are paragraphs, etc.
Ideally, a markup language does not specify formatting. That is the job of a style sheet. The preferred style sheet format for HTML (the only one I’m aware of, actually) is Cascading Style Sheets (CSS).
A style sheet might specify, for example, that all top level headings in a group of documents are to be styled as 24-point Palatino bold, or some other serif font if Palatino bold is not available. (HTML used to have formatting tags, which are now deprecated, but browsers still understand them).
And so, HTML tags should describe the structure of the content, while CSS declarations define the presentation of the content.
This is important because it is often necessary to separate presentation from content in order to serve the content to a user or program that needs a different presentation.
For example, how should a text-to-speech converter render text marked up as 24-point Palatino bold? The program might infer that the biggest font size in use on the page is for a top level heading, but the operation would be much more reliable if top level headings are clearly marked as such.
Separating content and presentation also helps with consistency. Suppose you have to specify 24-point Palatino bold over and over again for each top level heading and 20-point Palatino bold for each secondary level heading instead of defining them once each on a style sheet.
That opens up the potential for a whole bunch of mistakes, like for example, you might mistakenly style one secondary level heading as 51-point Palatino. And then that would throw off our hypothetical text-to-speech converter’s inference of what the top level heading is in the affected document.
One style sheet can format several documents, and one document can be formatted by different style sheets or combinations of style sheets. A style sheet can even be embedded into a document, but the separation of presentation and content still needs to be clearly discerned.
Although CSS has some animation capabilities, a document that is just HTML and CSS is rather static. This is where JavaScript comes in. JavaScript enables the document to change itself programmatically in response to user actions.
With JavaScript, it becomes a little more difficult to maintain the separation between content and presentation, as both are dynamically inserted into a document in ways that we might not always be able to foresee.
Though this is not as much of a concern for a game, like a Tic-Tac-Toe game. Making the game playable by the blind would require a lot more than proper structural markup. So the game I’ll start you off on will be for people with some level of sight.
We’ll do it in JavaScript, so you just need a suitable browser, like Firefox 65.0, and a plain text editor. On Windows that would be Notepad. On Mac OS X, you can use TextEdit, but be wary of its annoying tendency to want to turn everything to rich text.
In your plaint text editor, copy and paste the following:
<!DOCTYPE html>
<html>
<head>
<title>Tic-Tac-Toe</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="Play Tic-Tac-Toe against the computer." />
<style type="text/css"><!--h1 { font-family: Palatino, serif; font-size: 36pt }
table { width: 96%; border-collapse: collapse }
td { width: 32%; border: 25px solid black; font-size: 120pt;
font-family: sans-serif; text-align: center }
td#cell1 { border-left: none; border-top: none }
td#cell2 { border-top: none }
td#cell3 { border-top: none; border-right: none }
td#cell4 { border-left: none }
// td#cell5 { }
td#cell6 { border-right: none }
td#cell7 { border-left: none; border-bottom: none }
td#cell8 { border-bottom: none }
td#cell9 { border-bottom: none; border-right: none }
@media only screen and (max-width: 360px) {
td { font-size: 72pt }
}// --></style>
<script type="text/javascript"><!-- // PLACEHOLDER FOR JAVASCRIPT// --></script>
</head>
<body onload="gameInit();"><h1>Tic-Tac-Toe</h1><table>
<tr><td id="cell1" class="tttCell"> </td><td id="cell2" class="tttCell"> </td><td id="cell3" class="tttCell"> </td></tr>
<tr><td id="cell4" class="tttCell"> </td><td id="cell5" class="tttCell"> </td><td id="cell6" class="tttCell"> </td></tr>
<tr><td id="cell7" class="tttCell"> </td><td id="cell8" class="tttCell"> </td><td id="cell9" class="tttCell"> </td></tr>
</table></body>
</html>

Save it as TicTacToe.html
in a subfolder of your Documents folder, or wherever is convenient for you.
Depending on your operating system and default Web browser setting, you might see within your Documents folder something like the screenshot on the left. The screenshot was taken on a Windows 8 machine in which Mozilla Firefox is the default Web browser.
If you double-click the TicTacToe.html
icon, the Web page should open in a new tab on your default Web browser. In the following screenshot, we see the Firefox preview of what the page might look like on an iPhone 5.

You can click on the Tic-Tac-Toe board all you want, nothing is going to happen.
That’s because we haven’t really attached any JavaScript to this yet. The body
tag does include the onload="gameInit()"
declaration, but gameInit()
is not defined anywhere.
In fact, if you access the JavaScript console (with the F12 key, at least on Firefox for Windows), you will see the error message ReferenceError: gameInit is not defined
.
So the next step here is to define gameInit()
, a subroutine that will attach onclick
event listeners to the nine squares of the Tic-Tac-Toe board. Then, when the human player clicks one of the square, the captureSquare()
subroutine will be called.
Back in the plain text editor, delete the JavaScript placeholder and paste in the following:
var humanPlayerToken = "X";
var computerPlayerToken = "O";
var ticTacToeArray = [" ", " ", " ", " ", " ", " ", " ", " ",
" "];
var ticTacToeCells; function won(token) {
return false;
} function captureSquare() {
// PLACEHOLDER
} function gameInit() {
ticTacToeCells = document.getElementsByClassName("tttCell");
for (var i = 0; i < ticTacToeCells.length; i++) {
ticTacToeCells[i].addEventListener("click", captureSquare)
}
}
This defines some global variables to help the computer keep track of the squares.
Now, it might seem inefficient to use a variable with a16-letter name to refer to a single letter. And it is, for now. But it gives us the flexibility to later give the human player the ability to choose a token other than “X” without having to rewrite too much.
Most programming languages make very clear distinctions between subroutines that return values to the callers and subroutines that don’t. In the Pascal programming language, they are called functions and procedures.
For example, a subroutine that takes an angle and returns a cosine is rightly said to be a function, but a subroutine that takes and angle and displays it on the screen without returning anything to the caller is procedure.
JavaScript blurs the distinction between functions and procedures, as it has both of them defined with the keyword function
. Sometimes, the only way to tell whether a JavaScript subroutine returns a value or not is by the presence or absence of the return
keyword.
So won()
is a function that is supposed to check if the player identified by token
has captured three squares in a line: if that’s the case, it returns true
, if not it returns false
. However, in this early draft, it doesn’t actually check that, it just returns false
regardless.
Then captureSquare()
and gameInit()
are procedures, but they’re defined with the keyword function
. For now, captureSquare()
doesn’t do anything, it just has a “comment.”
Almost all programming languages have some syntax for comments, which are remarks that the parser ignores when compiling or interpreting the source code. Comments are a great way to set up “scaffolding” for your program.
In JavaScript, two consecutive forward slashes cause the parser to regard everything afterwards, up to the end of the line, as a comment. Eventually the placeholder comment in captureSquare()
will be replaced with actual JavaScript commands.
Lastly, gameInit()
attaches the event listeners to each td
element in the HTML document having class attribute tttCell
, after putting them in a collection with the document.getElementsByClassName()
function.
Note that in many programming languages, indexes start at 0, not 1. Thus our iterator through the collection of nine squares starts out at i = 0
, then is incremented as long as i < 9
(though it’s better form to not hard-code 9 as the threshold, and instead rely on the length
property of the squares collection).
This should be enough so that our program does not trigger any error or warning messages. But we still need to define what exactly captureSquare()
does before our program actually does anything visible.
For starters, it needs to put the human player’s token (“X” only for now) in the square, remove the event listener, and update the array. Edit captureSquare()
like this (new lines are in bold):
function captureSquare() {
this.innerText = humanPlayerToken;
this.removeEventListener("click", captureSquare);
var index = parseInt(this.id.substring(4)) - 1;
ticTacToeArray[index] = humanPlayerToken;
}
Since captureSquare()
will be called in response to the human player clicking on one of the board’s squares, the this
keyword will refer to that square, so we don’t actually need to know the square’s index to put the human player’s token in the square and remove the event listener.
The this
keyword in JavaScript is one of the most confusing aspects of JavaScript ever. Luckily, there are several articles here on Medium that explain it. If one of them doesn’t do it for you, look up another.
At this point it’s not terribly important to actually remove the event listener, since we’re not keeping track of the move count yet. If we were, we should not assume that no player would ever waste a move trying to capture a square they had already captured before.
We do need to know the captured square’s index to update the internal Tic-Tac-Toe array. If you look back at the HTML, you will see each of the cells has an HTML id
attribute from cell1
to cell9
. So we just need to extract that number and subtract 1 to put it in the range 0 to 8 in order to change ticTacToeArray
accordingly.

Save in the editor and refresh in the browser. Assuming no mistakes in the source (like misspellings in variable names or misplaced symbols), you should now be able to put an “X” in each of the nine squares.
Obviously this still requires more work to be a viable game. But at least you have verified that the event listeners are working as they should, so that the human player can place his or her first token in any of the nine squares.
Then the next step is to modify captureSquare()
so that it calls won()
to check if the human player has captured three aligned squares. If not, the computer should make its countermove. And of course we’ll need to actually write won()
, which I suggest we do by writing a helper function called checkLine()
.
function checkLine(indexA, indexB, indexC, token) {
return (ticTacToeArray[indexA] == token
&& ticTacToeArray[indexA] == ticTacToeArray[indexB]
&& ticTacToeArray[indexB] == ticTacToeArray[indexC]);
}
You can insert checkLine()
almost anywhere you want within the HTML script
tags, just as long as you take care not to insert it into another subroutine.
In most programming languages, =
means assign to a variable or constant, ==
means check if they’re equal. JavaScript has both of those, plus also ===
, a strict equality check, but hopefully ==
will be sufficient for our purposes.
Then won()
can be pretty much just a series of checkLine()
calls. We’ll have the function first check the three rows, then the three columns, and lastly the two diagonals. Delete the placeholder in won()
, and replace it with what’s bolded in the following:
function won(token) {
var winFlag = false;
var currIndex = 0;
while (currIndex < ticTacToeCells.length && !winFlag) {
winFlag = checkLine(currIndex, currIndex + 1, currIndex + 2,
token);
currIndex += 3;
}
currIndex = 0;
while (currIndex < 4 && !winFlag) {
winFlag = checkLine(currIndex, currIndex + 3, currIndex + 6,
token);
currIndex++;
}
if (!winFlag) {
winFlag = checkLine(0, 4, 8, token);
}
if (!winFlag) {
winFlag = checkLine(2, 4, 6, token);
}
return winFlag;
}
I could have written currIndex = currIndex + 3
and currIndex = currIndex + 1
, but I generally prefer the shortcuts currIndex += 3
and currIndex++
.
For some reason, long ago, someone decided that an exclamation as a prefix would mean “not.” So !true
is “not true,” meaning “false,” and !false
is “not false,” meaning “true.” A lot of languages, including JavaScript, followed suit, so this is now too entrenched to change.
Thus “if !winFlag
” means “if winFlag == false
,” so that if the function hasn’t found a winning line, it should keep looking.
There are too many hard-coded values for my liking here. But I don’t want to complicate things more than necessary. Next, we amend captureSquare()
:
function captureSquare() {
this.innerText = humanPlayerToken;
this.removeEventListener("click", captureSquare);
var index = parseInt(this.id.substring(4)) - 1;
ticTacToeArray[index] = humanPlayerToken;
if (won(humanPlayerToken)) {
notifyWinner(humanPlayerToken);
} else {
counterMove();
}
}
Now we will need to write notifyWinner()
and counterMove()
. For notifyWinner()
, a simple Web browser alert will suffice for now, you can add some flair and pizzazz later.
function notifyWinner(token) {
alert(token + "'s wins the game!");
}
I think this is probably about the point I should let you take over. I’ll write a simple counterMove()
that merely chooses the first available square, and then I leave it to you to rewrite the algorithm so that it plays more competitively.
function counterMove() {
var availableSquare = false;
var currIndex = 0;
while (currIndex < ticTacToeCells.length && !availableSquare) {
availableSquare = (ticTacToeArray[currIndex] == " ");
if (availableSquare) {
ticTacToeArray[currIndex] = computerPlayerToken;
ticTacToeCells[currIndex].innerText = computerPlayerToken;
ticTacToeCells[currIndex].removeEventListener("click",
captureSquare);
}
currIndex++;
}
if (won(computerPlayerToken)) {
notifyWinner(computerPlayerToken);
}
}
Here it becomes very important to remove the event listener from the square captured by the computer, because you don’t want the human player to be able to capture a square that the computer has captured.

Even so, with this version of counterMove()
, the only way the computer can win is if you let it. So, if you choose to continue with this project, your top priority is to rewrite counterMove()
so that the computer becomes capable of thwarting the human player from capturing three squares in a line. Such as by having it check if the human player has already captured two squares in a line.
Then, if you like, you could give the human player the ability to play O’s instead of X’s. You could use other letters, and even emoji, as tokens. Other possible improvements include a fancier winner notification and the ability to reset the board without having to refresh the page. And some way to draw a line through the winning captured squares. These improvements would require learning more not just about JavaScript but also learning more about HTML and CSS.
I hope that this exercise proves to you that you too can learn how to “code.” You might also want to learn programming methodologies, like “Agile” and test-driven development, but I’m sure you’re also capable of learning those.
The more important question, and one I don’t have an answer to, is: how do you get a job in this field if you’re not a twenty-something white guy?
Lack of experience in a programming job is of course a shortcoming for a young white male applicant, but an understandable one. That understanding does not generally extend to other demographics of job applicants.
One slightly encouraging thing I have noticed, however, is that, regardless of your race, if you can get your first programming job and hold on to it for a few months, recruiters will try to poach you for another company.
You are only as desirable to one software company as you’re desirable to another software company. How “good” you are at “coding” is just one factor, and hardly the biggest obstacle.