Winning
Home What is Logo? Getting Logo Logo Lessons Tic-Tac-Toe Downloads

 

Design
Programming
Initialize
Grid
Winning
Two Player
Single Player

Back Up Next

Marking a Win

When we have a winner, we want to draw a line. This word "win.line" will draw a line between two points to indicate a win.

Editor
to win.line :f :t
    ;
    ; draw a line through winning pieces
    ;
    setpensize [1 1]
    setpc [0 0 0]
    pu
    setpos :f
    pd
    setpos :t
    pu
end

Simple enough, now let's test it (you should see three O's and a line through them):

Commander
init
place 0 place 1 place 2
win.line pos.from.index 0 pos.from.index 2

Have I Won?

We'll split up the win checking into two words "check.win.row" and "check.win". This way, we can put most of the work on how the computer determines if a row has won, and then proceed to check all the possible winning combinations. Remember the grid earlier? A simple winning row would be through boxes 0, 1 and 2.  Let's write the code to check a row of three boxes, and draw the line if we detect a win:

Editor
to check.win.row :a :b :c
    ;
    ; output "true if
    ; row is a winning row
    ; and draw a line through it (from :a to :c)
    ;
    localmake "win (AND grid.me :a grid.me :b grid.me :c)
    if :win [win.line pos.from.index :a pos.from.index :c]
    output :win
end

Notice the word "AND"? This word will return the word "true" if (and only if) all the values specified are considered true. For example, if a teacher asks, "did you all do your homework?" then the answer is yes only if each and every person did his or her homework. In this case, we determine a win if all three squares have our piece. We determine if a square has the same game piece as "turn" using the word "grid.me". If you want to understand how "AND" works, try the following in the commander:

Commander
show AND "false "false
false 
show AND "true "false
false
show AND "false "true
false
show AND "true "true
true 

Check to see if "check.win.row" works:

Commander
init
show :turn
O 
place 0 place 1 place 2
show check.win.row 0 1 2
true 
show check.win.row 3 4 5
false 
show check.win.row 0 3 6
false 

You should see a line through the winning row. We'll use this word for each winning sequence of 3 squares. In this case, we use the word "OR", meaning, "If any of the cases are true". Type the following to understand how "OR" differs from "AND":

Commander
show OR "false "false
false 
show OR "true "false
true 
show OR "false "true
true 
show OR "true "true
true 

Enter the definition for "check.win" using the editor:

Editor
to check.win
    ;
    ; output "true if
    ; current player has any row's
    ;
    output (OR check.win.row 0 1 2
              check.win.row 3 4 5
              check.win.row 6 7 8
              check.win.row 0 3 6
              check.win.row 1 4 7
              check.win.row 2 5 8
              check.win.row 0 4 8
              check.win.row 6 4 2)
end

And check it:

Commander
init
show check.win
false 
place 3 place 4 place 5
show check.win
true 

If you wish, try specifying other squares using the place command.

Can I Move?

After each turn, we need to see if the current player has won or not. If they haven't won, we need to check for a draw. We can check for a draw by seeing if there are any "?" in the grid. If there are not, then it's a draw. Checking for a win is easy, using the "check.win" word. If we want to ask, "have we not won" then we can use the word "NOT" as follows:

Commander
show "true
true 
show "false
false 
show not "true
false 
show not "false
true 
show AND "true (not "false)
true 
init
show check.win
false 
show not check.win
true 

Another word we'll use is "memberp" (meaning member predicate). This is a fancy way of us to ask, "are there any words in 'grid' that are '?' ?" If there are, it will return "true" (yes) otherwise "false" (no).

Editor
to canmove
    ;
    ; output "true if
    ; 1) there are any spare slots, and
    ; 2) current player hasn't won
    ;
    output (AND (memberp "? :grid) (not check.win))
end

Once you have written the "canmove" word, you can test it:

Commander
init
show canmove
true 
place 6 place 7
show canmove
true 
place 8
show canmove
false 

Back Up Next

 

Comments to WebMaster