patternModerate
Four Tic-Tac-Toe boards using kTurtle
Viewed 0 times
kturtletoeticfourboardstacusing
Problem
I am trying to learn kTurtle (slightly different from Logo) so that I can help my daughter learn to write code. I have decided that I would write a program that would play Tic-Tac-Toe with a user. So far, all I have is the
I am using kTurtle on Ubuntu which is similar to Logo but open source (free).
What I really want to know is if I am following good programming standards as this is a little different than what I am used to coding.
Here is the finished product:
Game board, and I make it more than just a single board to add to the intensity of my learning. Hopefully I can get this figured out before my daughter graduates high school.I am using kTurtle on Ubuntu which is similar to Logo but open source (free).
What I really want to know is if I am following good programming standards as this is a little different than what I am used to coding.
#Game board 1
$CanvasX = 300
$CanvasY = 300
#$x = ask "how big do you want the canvas to be?"
canvassize $CanvasX, $CanvasY
$x=$CanvasX/2
$y=$CanvasY/2
learn gameboard $a, $b, $x, $y {
$TwoThirdsX = ($x/3)*2
$OneThirdX = $x/3
go $a, $b
dir 180
penup
forward $OneThirdX
turnleft 90
pendown
forward $x
penup
turnright 90
forward $OneThirdX
turnright 90
pendown
forward $x
penup
turnleft 90
forward $OneThirdX
turnleft 90
forward $OneThirdX
turnleft 90
pendown
forward $x
penup
turnright 90
forward $OneThirdX
pendown
turnright 90
forward $x
}
penwidth 1
gameboard 0, 0, $x, $y
$a=$x
$b=0
gameboard $a,$b,$x,$y
$a=$x
$b=$y
gameboard $a,$b,$x,$y
$a=0
$b=$y
gameboard $a,$b,$x,$y
penwidth 5
go $x, 0
forward 2*$x
go 0, $y
turnleft 90
forward 2*$yHere is the finished product:
Solution
I've just installed KTurtle for Windows, and ran your code. I never thought a turtle could be so frantic! KTurtle is ..entertaining to see in action! I've played with LogoWriter back in high school, an eternity ago; this is very similar (although I was somehow expecting a 16-color, 320x240 resolution.. the shock it was!).
Save often.
KTurtle works on Windows, but it sometimes crashes when you click to run your script. Save often; save every time you want to run it, and it's workable. Also whatever you do, don't undock the code pane, it seems impossible to dock it back into the IDE afterwards (and restarting the IDE won't help). If you have access to KTurtle on Ubuntu, by all means don't bother with Windows (assuming it's more stable on Ubuntu).
So I ran it again, at a slower speed.. first thing I'm noticing is that you're missing a
Your algorithm is drawing the 4 boards clockwise, starting top-left. Each board is made of 2 horizontal and 2 vertical lines, which means if you skip drawing the larger/bolder lines in the center, the canvas looks like this:
Your algorithm takes good care of not drawing the same line twice and gets the job done, but there's no separation of concerns whatsoever - as was mentioned in @Sjlver's answer, you need abstractions; teaching a kid how to get things done is nice, teaching the kid how to think in terms of abstractions is even nicer. I would go by @Sjlver's recommendation and create a command responsible for drawing a single square (
Notice the
I like that you're using
So, now you have a command that can draw a square; now you need one that draws 9 of them to draw a board:
And now you can have code like this:
It's slower than your code, and it's not as efficient (pretty much every line get drawn more than once), but thinking in abstractions, in terms of functions that do only one thing, is more important than getting a script to do what you need it to do.
This is the result:
Now you want have a black border around each board, right? The code to do that is pretty much already written!
Now this leaves the "script" part doing 3 things: declaring global-scope variables, drawing the boards, and drawing the outlines. Here's the final script, with the result:
The "script" part is now only in charge of controlling the high-level stuff; the lower-level actual looping and drawing is abstracted away into commands with meaningful names, that start with a verb, and as a bonus, the turtle ends up right in the middle!
Save often.
KTurtle works on Windows, but it sometimes crashes when you click to run your script. Save often; save every time you want to run it, and it's workable. Also whatever you do, don't undock the code pane, it seems impossible to dock it back into the IDE afterwards (and restarting the IDE won't help). If you have access to KTurtle on Ubuntu, by all means don't bother with Windows (assuming it's more stable on Ubuntu).
So I ran it again, at a slower speed.. first thing I'm noticing is that you're missing a
clear at the beginning of the script (/program?), so that successive executions start off an empty canvas.Your algorithm is drawing the 4 boards clockwise, starting top-left. Each board is made of 2 horizontal and 2 vertical lines, which means if you skip drawing the larger/bolder lines in the center, the canvas looks like this:
Your algorithm takes good care of not drawing the same line twice and gets the job done, but there's no separation of concerns whatsoever - as was mentioned in @Sjlver's answer, you need abstractions; teaching a kid how to get things done is nice, teaching the kid how to think in terms of abstractions is even nicer. I would go by @Sjlver's recommendation and create a command responsible for drawing a single square (
learn square), and use a repeat loop to keep the code DRY:learn square $x, $y, $size {
go $x, $y
repeat 4 {
edge $size, 90
}
}
learn edge $size $angle {
forward $size
turnright $angle
}Notice the
square command is only responsible for drawing 4 edges at the specified coordinates - the edge command is responsible for drawing a single line and turning the turtle in the specified direction. It is not responsible for knowing whether or not the pen is up or down.I like that you're using
penup and pendown instead of the shorthand pu and pd - you've used the easier-to-read ones and that's good.So, now you have a command that can draw a square; now you need one that draws 9 of them to draw a board:
learn board $x, $y {
for $w = 0 to 2 {
for $h = 0 to 2 {
square $x + $w * $boxSize, $y + $h * $boxSize, $boxSize
}
}
}And now you can have code like this:
$boardSize = 150
$boxSize = $boardSize/3
# number of boards to draw in each direction:
$boards = 2
clear
pendown
penwidth 1
for $x = 0 to $boards-1 {
for $y = 0 to $boards-1 {
board $x * $boardSize, $y * $boardSize
}
}It's slower than your code, and it's not as efficient (pretty much every line get drawn more than once), but thinking in abstractions, in terms of functions that do only one thing, is more important than getting a script to do what you need it to do.
This is the result:
Now you want have a black border around each board, right? The code to do that is pretty much already written!
penwidth 5
for $x = 0 to $boards - 1 {
for $y = 0 to $boards - 1 {
square $x * $boardSize, $y * $boardSize, $boardSize
}
}Now this leaves the "script" part doing 3 things: declaring global-scope variables, drawing the boards, and drawing the outlines. Here's the final script, with the result:
learn square $x, $y, $size {
go $x, $y
repeat 4 {
edge $size, 90
}
}
learn edge $size, $angle {
turnright $angle
forward $size
}
learn board $x, $y {
for $w = 0 to 2 {
for $h = 0 to 2 {
square $x+$w*$boxSize, $y+$h*$boxSize, $boxSize
}
}
}
learn drawBoards {
for $x = 0 to $boards-1 {
for $y = 0 to $boards-1 {
board $x*$boardSize, $y*$boardSize
}
}
}
learn drawOutlines {
for $x = 0 to $boards-1 {
for $y = 0 to $boards-1 {
square $x*$boardSize, $y*$boardSize, $boardSize
}
}
}
$boardSize = 150
$boxSize = $boardSize/3
$boards = 2
clear
pendown
penwidth 1
drawBoards
penwidth 5
drawOutlinesThe "script" part is now only in charge of controlling the high-level stuff; the lower-level actual looping and drawing is abstracted away into commands with meaningful names, that start with a verb, and as a bonus, the turtle ends up right in the middle!
Code Snippets
learn square $x, $y, $size {
go $x, $y
repeat 4 {
edge $size, 90
}
}
learn edge $size $angle {
forward $size
turnright $angle
}learn board $x, $y {
for $w = 0 to 2 {
for $h = 0 to 2 {
square $x + $w * $boxSize, $y + $h * $boxSize, $boxSize
}
}
}$boardSize = 150
$boxSize = $boardSize/3
# number of boards to draw in each direction:
$boards = 2
clear
pendown
penwidth 1
for $x = 0 to $boards-1 {
for $y = 0 to $boards-1 {
board $x * $boardSize, $y * $boardSize
}
}penwidth 5
for $x = 0 to $boards - 1 {
for $y = 0 to $boards - 1 {
square $x * $boardSize, $y * $boardSize, $boardSize
}
}learn square $x, $y, $size {
go $x, $y
repeat 4 {
edge $size, 90
}
}
learn edge $size, $angle {
turnright $angle
forward $size
}
learn board $x, $y {
for $w = 0 to 2 {
for $h = 0 to 2 {
square $x+$w*$boxSize, $y+$h*$boxSize, $boxSize
}
}
}
learn drawBoards {
for $x = 0 to $boards-1 {
for $y = 0 to $boards-1 {
board $x*$boardSize, $y*$boardSize
}
}
}
learn drawOutlines {
for $x = 0 to $boards-1 {
for $y = 0 to $boards-1 {
square $x*$boardSize, $y*$boardSize, $boardSize
}
}
}
$boardSize = 150
$boxSize = $boardSize/3
$boards = 2
clear
pendown
penwidth 1
drawBoards
penwidth 5
drawOutlinesContext
StackExchange Code Review Q#53828, answer score: 11
Revisions (0)
No revisions yet.