Programming Tic-Tac-Toe in Java


<<Previous | ToC | Next >>
 

ASCII Graphics TTT Board

If you have been following along in English, and your code works, you are ready to rewrite the same program in Java. If you skipped over those parts, you will have less design experience, but you might benefit from reading the commentary, perhaps some time when you feel like taking a break from coding. If you do not have English-ready code, but you did do a full English program, you will start there. Otherwise, feel free to start with my English code here.

Me, I think working through the English helps you to better understand what the code is and should be doing, which will result in better code and fewer bugs, but other people have a different opinion. We live in a very wealthy economy, with much excess money to pay for inefficient programmers. When (not if) that goes away, the inefficient programmers will be replaced by much cheaper (but still inefficient) programmers in India and Belarus and other third-world countries trying to catch up by working harder. Those other programmers already exist, and you compete with them by being both smarter and here.

Anyway, here is my version of the TTT Scoring program in English, without the English-specific modifications. Your code (if you did it) may be different, but if it works, use it:

Initialize board
let turns = 0
Repeat 10 times
  Show current board
  if turns>8, exit
  if turns>4 do Test for win
  If won, exit
  let turns = turns+1
  if who = "X" let who = "O"
    otherwise let who = "X"
  print "input for " who
  Repeat
    Input play -1
    Round play
    if play<1 do it again
    if play>9 do it again
    let tmp = board[play]
    if tmp<"A" exit
    Next
  Update board
  Next
If won, Say who " won"
otherwise say "Cat's"

"Initialize board"
  print "Initialize board"
  let who = "O"
  let won = false
  let board = "0123456789"
  let turns = 0
  Done

"Show current board"
  print "Show current board"
  Variable step = 0
  Repeat 3
    let line = ""
    let cols = 0
    Repeat 3
      let step = step+1
      let cols = cols+1
      let square = board[step]
      let line = line # " " # square # " "
      if cols<3 let line = line # "|"
      Next
    Show line
    if step<9 Show "---+---+---"
    Next
  Done

"Update board"
  print "Update board: " who " => [" play "]"
  put who into board[play]
  Done

"Test for win"
  print "Test for win"
  Repeat 1
    let prms = 123
    ThreeInaRow
    if won exit
    let prms = 456
    ThreeInaRow
    if won exit
    let prms = 789
    ThreeInaRow
    if won exit
    let prms = 147
    ThreeInaRow
    if won exit
    let prms = 258
    ThreeInaRow
    if won exit
    let prms = 369
    ThreeInaRow
    if won exit
    let prms = 159
    ThreeInaRow
    if won exit
    let prms = 357
    ThreeInaRow
    Next
  Done

"ThreeInaRow"
  let won = false
  let first = board[prms[0]]
  let mid = board[prms[1]]
  let last = board[prms[2]]
  if first=who if mid=who if last=who let won = true
  Done


The hardest -- and it isn't very hard -- part of converting English to Java is dealing with arrays (which in English we did as text strings). So I will give you some direction with that. Then you know how to do the rest.
 

Game Board Details

Back in an early part of the design phase we discussed how to implement the game board as a Java array, but left the details for later. That later is now.

Not counting where the word "board" is used as part of a subroutine name, there are four places in this English program that touch the game board. You should review those four places now to get in your mind how we use the board in those four places.

1. In subroutine "Initialize board" we initialize the board to the beginning state.  This happens only once at the beginning, and is therefore least important to us for deciding how to encode the board for the rest of the program, because we can (and should) do the initialization to conform to the rest of the usage, not the other way around.

2. In subroutine "Show current board" we display on the system console the current board state. This might suggest to us what is convenient for output, but it is less important than how the board is used in the program's inner workings. This could be a tie-breaker between two alternative encodings, but not much more.

3. In subroutine "Update board" we update the board with the latest play. This happens only once for each play (maximum nine times), and again is less important than how the board is used in the program's inner workings.

4. Subroutine "ThreeInaRow" does all the heavy lifting. It is called up to eight times for each play, and accesses the board three times each call. If we are concerned about code efficiency, here is where it matters. If we are concerned about perspecuity (ease of understanding what we are doing), here again is where it matters. At this stage in your development, and for a program this size, perspecuity is more important than efficiency.

So why don't you think about what representation of the game board makes most sense to you, and then turn the page.

<<Previous | ToC | Next >>

Revised: 2021 August 30