
uniquename 2013aug01The image above, at 'external site' mini.net, has gone dead. Here are a couple of 'locally stored' images, on this wiki site --- of the game board and of the game's help window.
##+##########################################################################
#
# tkPente -- Plays pente between two players, both classic and Keryo rules
#
package require Tk
##+##########################################################################
#
# init - One time initializtion stuff
#
proc init {} {
global cl st sz bd
set st(rules) pente
set cl(1) green3
set cl(1,m) #00A000
set cl(-1) blue
set cl(-1,m) #000080
set cl(bg) burlywood3
set cl(bg) [::tk::Darken burlywood3 110]
set cl(bg2) [::tk::Darken $cl(bg) 110] ;# For button active
set cl(fn) "-Adobe-Helvetica-Bold-R-Normal--*-140-*-*-*-*-*-*"
set cl(fn2) "-Adobe-Courier-Bold-R-Normal--*-100-*"
catch {set cl(fn2) [font create -family courier -size 10 -weight bold]}
set sz(pip) 16 ;# Size of a pip
set sz(pip2) [expr {$sz(pip) / 2}]
set sz(gap) 2 ;# Gap between pips
set sz(gap2) [expr {$sz(gap) / 2}]
set sz(pipg) [expr {$sz(pip) + $sz(gap)}] ;# Pip size plus gap
set sz(sq) 18 ;# Number of lines
set sz(sq2) [expr {$sz(sq)/2}]
set sz(bd) $sz(pip2) ;# Border around edge
set sz(size) [expr {$sz(pipg) * $sz(sq) + 2*$sz(bd)}]
set sz(size2) [expr {$sz(size) / 2}]
set sz(side) [expr {2 * $sz(pip) + 4*$sz(gap)}]
set sz(side2) [expr {$sz(side) / 2}]
new_game ;# Do per game init
}
##+##########################################################################
#
# new_game - Per game initialization stuff
#
proc new_game {} {
global sz bd cl st
set st(t) 1 ;# Whose turn it is
set st(n) 1 ;# Turn number
set st(v) 0 ;# Someone has won
set st(cl) $cl($st(t)) ;# Active color
set st(cl,m) $cl($st(t),m) ;# Active color for mouse move
set st(capt,1) 0 ;# Number of captures
set st(capt,-1) 0
set st(capt,sum,1) 0 ;# Number of captured pieces
set st(capt,sum,-1) 0
set st(undo) ""
set st(redo) ""
set st(c) ""
set st(msg) ""
;# Initialize the board
for {set r -$sz(sq2)} {$r <= $sz(sq2)} {incr r} {
for {set c -$sz(sq2)} {$c <= $sz(sq2)} {incr c} {
set bd($r,$c) 0
}
}
catch {.c delete pip} ;# Erase the board
catch {.p1 delete pip}
catch {.p2 delete pip}
catch {draw_turn_number $st(n)}
catch {do_move 0 0}
catch {.bundo config -state disabled}
catch {.m.game.m entryconfigure 3 -state disabled}
set st(undo) "" ;# Nothing to undo
}
##+##########################################################################
#
# draw_board - Draws the playing board and sideboard with all its
# lines and frills.
#
proc draw_board {} {
global sz cl
catch {destroy .ftop .c .p1 .p2}
pack [frame .ftop] -side top
canvas .c -width $sz(size) -height $sz(size) -bd 4 -relief raised
.c config -cursor crosshair
.c xview moveto 0 ; .c yview moveto 0
.c config -bg $cl(bg)
canvas .p1 -height $sz(size) -width $sz(side) -bg $cl(bg)
canvas .p2 -height $sz(size) -width $sz(side) -bg $cl(bg)
foreach w {.c .p1 .p2} {$w config -highlightthickness 0}
pack .p1 .c .p2 -in .ftop -side left -fill y
;# Draw all the lines
for {set i -$sz(sq2)} {$i <= $sz(sq2)} {incr i} {
set width 1
if {$i == 0} {set width 2}
set c1 [pos2coord $i -$sz(sq2)]
set c2 [pos2coord $i $sz(sq2)]
eval .c create line $c1 $c2 -width $width
set c1 [pos2coord -$sz(sq2) $i]
set c2 [pos2coord $sz(sq2) $i]
eval .c create line $c1 $c2 -width $width
}
;# Draw little dots 3 out
foreach {r c} {-3 -3 -3 3 3 3 3 -3} {
set c1 [eval expand 3 [pos2coord $r $c]]
.c create oval $c1 -fill $cl(bg)
}
set row [expr {.5 - $sz(sq2)}]
for {set i 0} {$i < 4} {incr i} {
foreach {x y} [pos2coord $row [expr {-8.5 + $i}]] {}
set text [string index "Turn" $i]
.c create text $x $y -text $text -anchor c
}
.c create text [pos2coord $row -3.5] -text "" -anchor c -tag {label label1}
.c create text [pos2coord $row -2.5] -text "" -anchor c -tag {label label2}
.c create text [pos2coord $row -1.5] -text "" -anchor c -tag label3
wm title . "tkPente by Keith Vetter"
bind .c <Motion> {mouse_move %x %y}
bind .c <B1-ButtonRelease> {do_move2 %x %y}
bind .c <Leave> {.c delete cursor ; set st(c) ""}
bind .c <Shift-Button-3> {null_turn %x %y}
}
##+##########################################################################
#
# draw_side - Draws the frills for the side capture panels
#
proc draw_side {} {
global sz cl
set text "CAPTURES"
set tlen [string length $text]
set top [expr {-$sz(sq2) + .5}]
set interval [expr {-2*$top / ($tlen - 1)}]
for {set i 0} {$i < $tlen} {incr i} {
set letter [string index $text $i]
set row [expr {$top + $interval * $i}]
set y [lindex [pos2coord $row 0] 1]
.p1 create text $sz(side2) $y -anchor c -text $letter -font $cl(fn)
.p2 create text $sz(side2) $y -anchor c -text $letter -font $cl(fn)
}
}
##+##########################################################################
#
# draw_pip - Draws a pip at given row and column
#
proc draw_pip {r c color {tags ""}} {
global sz
set cl [eval expand $sz(pip2) [pos2coord $r $c]]
lappend tags p_${r}_$c pip
set id [.c create oval $cl -fill $color -tag $tags]
.c itemconfig $id -outline white
return $id
}
##+##########################################################################
#
# draw_pip_xy - Like draw_pip but for any window and any coordinate
#
proc draw_pip_xy {w x y color {tags ""}} {
global sz
set cl [expand $sz(pip2) $x $y]
lappend tags pip
set id [$w create oval $cl -fill $color -tag $tags]
$w itemconfig $id -outline white
return $id
}
##+##########################################################################
#
# undraw_pip - Erases a pip at row, column
#
proc undraw_pip {r c} {
.c delete p_${r}_$c
}
##+##########################################################################
#
# draw_capture - Draws the captured pip in the side capture panels
#
proc draw_capture {who cnt type} {
global st sz cl
if {$cnt <= 0 || $cnt > 8} return
if {$st(rules) == "pente" && $cnt > 5} return ;# Out of range
set w ".p[expr {(3 - $who) / 2}]" ;# Which window
set text "CAPTURES"
set tlen [string length $text]
set top [expr {-$sz(sq2) + .5}]
set interval [expr {-2*$top / ($tlen - 1)}]
set row [expr {$top - .5 + $interval * ($cnt - .5)}]
set y [lindex [pos2coord $row 0] 1]
set x1 [expr {$sz(side2) - $sz(gap2) - $sz(pip2)}]
set x2 [expr {$sz(side2) + $sz(gap2) + $sz(pip2)}]
set color $cl([expr {-$who}])
draw_pip_xy $w $x1 $y $color pip$cnt
draw_pip_xy $w $x2 $y $color pip$cnt
if {$type == 1} return
set x $sz(side2)
set y [lindex [pos2coord [expr {$row + .9}] 0] 1]
draw_pip_xy $w $x $y $color pip$cnt
}
##+##########################################################################
#
# draw_turn_number - Updates the turn number on the board
#
proc draw_turn_number {n} {
set n [expr {($n+1) / 2}]
.c itemconfig label3 -text [expr {$n % 10}]
.c itemconfig label -text "" ;# Erase upper digits
if {$n >= 10} { ;# Draw upper digits if needed
.c itemconfig label2 -text [expr {($n / 10) % 10}]
if {$n >= 100} {
.c itemconfig label1 -text [expr {($n / 100) % 10}]
}
}
}
##+##########################################################################
#
# darken_all - Used after a victory to darken all but the winning combination
#
proc darken_all {who n pips} {
global cl
.c itemconfig pip1 -fill $cl( 1,m) -outline gray80
.c itemconfig pip-1 -fill $cl(-1,m) -outline gray80
.p1 itemconfig pip -fill $cl(-1,m) -outline gray80
.p2 itemconfig pip -fill $cl( 1,m) -outline gray80
if {$n == 2} { ;# Win by capture
set w ".p[expr {(3 - $who) / 2}]"
$w itemconfig pip -fill $cl([expr {-$who}]) -outline white
return
}
foreach p $pips {
.c itemconfig $p -fill $cl($who) -outline white
}
}
##+##########################################################################
#
# undarken_all - Undoes the affect of darken_all
#
proc undarken_all {} {
global cl
.c itemconfig pip1 -fill $cl( 1) -outline white
.c itemconfig pip-1 -fill $cl(-1) -outline white
.p1 itemconfig pip -fill $cl(-1) -outline white
.p2 itemconfig pip -fill $cl( 1) -outline white
}
##+##########################################################################
#
# draw_buttons - Draws the buttons below the board
#
proc draw_buttons {} {
global cl
set hlt highlightthickness
frame .fmid -background $cl(bg) -bd 2 -relief ridge
frame .fbot -background $cl(bg) -bd 2 -relief ridge
pack .fbot .fmid -side bottom -expand y -fill x
label .pl1 -text "Player 1" -bg $cl(1) -$hlt 0 -font $cl(fn) \
-bd 2 -relief raised -pady 3 -padx 5
label .pl2 -text "Player 2" -bg $cl(-1) -$hlt 0 -font $cl(fn) \
-bd 2 -relief raised -pady 3 -padx 5
label .msg -bg $cl(bg) -$hlt 0 -font $cl(fn) -textvariable st(msg)
pack .pl1 -in .fmid -side left
pack .pl2 -in .fmid -side right
pack .msg -in .fmid -side left -expand 1 -fill x
button .bundo -text Undo -command undo -state disabled
button .bstart -text "New Game" -width 8 -command new_game -padx 5
button .bquit -text Quit -command exit
foreach b {.bundo .bstart .bquit} {
$b config -bg $cl(bg) -activebackground $cl(bg2) -font $cl(fn) -$hlt 0
}
pack .bundo .bstart .bquit -in .fbot -side left -expand 1 -pady 2m
}
proc draw_menus {} {
global cl
frame .m -bg $cl(bg)
pack .m -side top -fill x -expand yes
menubutton .m.game -text Game -underline 0 -menu .m.game.m -relief flat \
-bg $cl(bg) -activebackground $cl(bg) -bd 2
menubutton .m.help -text Help -underline 0 -menu .m.help.m -relief flat \
-bg $cl(bg) -activebackground $cl(bg) -bd 2
foreach w [list .m.help .m.game] {
bind $w <Enter> [list $w config -relief raised]
bind $w <Leave> [list $w config -relief flat]
}
pack .m.game .m.help -side left
menu .m.game.m -tearoff 0 -bg $::cl(bg)
.m.game.m add radio -label "Standard Pente" -under 0 \
-value pente -variable st(rules) -command new_game
.m.game.m add radio -label "Keryo Pente" -under 0 \
-value keryo -variable st(rules) -command new_game
.m.game.m add separator
.m.game.m add command -label Undo -under 0 -command undo -state disabled
.m.game.m add separator
.m.game.m add command -label "New Game" -under 0 -command new_game
.m.game.m add separator
.m.game.m add command -label Exit -under 0 -command exit
menu .m.help.m -tearoff 0 -bg $::cl(bg)
.m.help.m add command -label Help -underline 0 -command help
return
menu .m -tearoff 0
. configure -menu .m ;# Attach menu to main window
# Top level menu buttons
.m add cascade -menu .m.game -label "Game" -underline 0
.m add cascade -menu .m.help -label "Help" -underline 0
menu .m.game -tearoff 0
.m.game add command -label Undo -under 0 -command undo -state disabled
.m.game add separator
.m.game add command -label "New Game" -under 0 -command new_game
.m.game add separator
.m.game add command -label Exit -under 0 -command exit
menu .m.help -tearoff 0
.m.help add command -label Help -under 0 -command Help
}
##+##########################################################################
#
# draw_cross_hairs - Draws some cross hairs on a given row,col
#
proc draw_cross_hairs {row col} {
global cl
.c delete cross ;# Get rid of old
foreach {x y} [pos2coord $row $col] {}
foreach {l t r b} [expand 4 $x $y] {}
.c create line $l $b $r $t -tag cross -fill white -width 2
.c create line $l $t $r $b -tag cross -fill white -width 2
return
}
#############################################################################
#############################################################################
##+##########################################################################
#
# pos2coord - Converts row,col into x,y
#
proc pos2coord {r c} {
global sz
set r [expr {$r + $sz(sq2)}]
set c [expr {$c + $sz(sq2)}]
set x [expr {$sz(bd) + $c * $sz(pipg)}]
set y [expr {$sz(bd) + $r * $sz(pipg)}]
return [list $x $y]
}
##+##########################################################################
#
# coord2pos - Converts x,y into row,col
#
proc coord2pos {x y} {
global sz
set x [expr {round($x + $sz(pip2))}]
set y [expr {round($y + $sz(pip2))}]
set r [expr {(($y - $sz(bd)) / $sz(pipg)) - $sz(sq2)}]
set c [expr {(($x - $sz(bd)) / $sz(pipg)) - $sz(sq2)}]
return [list $r $c]
}
##+##########################################################################
#
# expand - Grows rectangle a,b,c,d by n units
#
proc expand {n a b {c -999} {d -999}} {
if {$c == -999} { set c $a ; set d $b }
return [list [expr {$a - $n}] [expr {$b - $n}] \
[expr {$c + $n}] [expr {$d + $n}]]
}
##+##########################################################################
#
# mouse_move - Handles drawing a pip under the mouse as it moves.
#
proc mouse_move {x y} {
global st bd
if $st(v) return ;# Game over
set x [.c canvasx $x] ;# Convert to canvas coordinates
set y [.c canvasy $y]
foreach {r c} [coord2pos $x $y] {}
if {$st(n) == 3 && $r < 3 && $r > -3 && $c < 3 && $c > -3} {
.c delete cursor ;# Restricted move
set st(c) ""
return
}
set m [list $r $c]
if [string match $m $st(c)] return ;# In the same location
set st(c) ""
.c delete cursor
if {[info exists bd($r,$c)] && $bd($r,$c) == 0} {
draw_pip $r $c $st(cl,m) cursor
set st(c) $m
}
update
}
##+##########################################################################
#
# do_move2 - Like do_move but with coordinates in x,y instead of row, column
#
proc do_move2 {x y} {
set x [.c canvasx $x]
set y [.c canvasy $y]
eval do_move [coord2pos $x $y]
}
##+##########################################################################
#
# do_move - Handles a move to row, column by the current player
#
proc do_move {r c} {
global bd st cl
.c delete cursor ; set st(c) "" ;# Delete mouse cursor
if $st(v) return ;# Game over
if {$bd($r,$c) != 0} { return [bell] }
if {$st(n) == 3 && $r < 3 && $r > -3 && $c < 3 && $c > -3} {
bell ;# This move is restricted
return
}
set id [draw_pip $r $c $st(cl) pip$st(t)] ;# Draw the pip here
draw_cross_hairs $r $c
set bd($r,$c) $st(t)
set capture [check_capture $r $c $st(t)]
foreach {cnt cnt3} $capture break
set undo [concat $r $c $capture]
set st(undo) "[list $undo] $st(undo)"
if {[info exists ::debug] && $::debug == 1} {
puts "capture $capture"
puts "undo $undo"
puts "st(undo) $st(undo)"
}
.bundo config -state normal
.m.game.m entryconfigure 3 -state normal
if {$cnt > 0} { ;# Draw the captures
set capt $st(capt,$st(t))
incr st(capt,$st(t)) $cnt ;# One more capture event
incr st(capt,sum,$st(t)) [expr {2 * $cnt + $cnt3}]
for {set i [incr capt]} {$i <= $st(capt,$st(t))} {incr i} {
draw_capture $st(t) $i [expr {[incr cnt3 -1] >= 0 ? 2 : 1}]
}
}
draw_turn_number [incr st(n)] ;# New turn
foreach {w pips} [check_win $r $c $st(t)] break ;# Did someone win?
if {$w != 0} { ;# A VICTORY!!!
set who [expr {$st(t) == 1 ? 1 : 2}] ;# Who won
if {$w == 3} {
set st(msg) "Player $who won -- 15 captures"
} elseif {$w == 2} {
set st(msg) "Player $who won -- 5 captures"
} else {
set st(msg) "Player $who won -- 5 in a row"
}
darken_all $st(t) $w $pips
set st(v) 1
}
change_turn
return $id
}
##+##########################################################################
#
# null_turn - Lets the user skip a turn. Useful for setting up a board.
# Works by pretending the user moved to -999,-999.
#
proc null_turn {x y} {
global st
.c delete cursor cross
draw_turn_number [incr st(n)] ;# New turn
change_turn ;# Other person can go
set st(c) ""
mouse_move $x $y
set st(undo) "{-999 -999 0 0} $st(undo)"
}
##+##########################################################################
#
# change_turn - Changes the state to be the other players turn.
#
proc change_turn {} {
global st cl
set st(t) [expr {-$st(t)}] ;# Change whose turn it is
set st(cl) $cl($st(t)) ;# Active color
set st(cl,m) $cl($st(t),m) ;# Active color for mouse move
}
##+##########################################################################
#
# check_capture - Sees what pieces have been captured
#
proc check_capture {r c me} {
global bd st
set cnt 0
set cnt3 0 ;# Triple captures
set you [expr {-$me}]
set undo "" ;# So we can undo it
foreach {dr dc} {-1 0 -1 -1 -1 1 0 -1 1 -1 1 0 1 1 0 1} {
set r1 [expr {$r + $dr}]
set c1 [expr {$c + $dc}]
if {[info exists bd($r1,$c1)] == 0 || $bd($r1,$c1) != $you} continue
set r2 [expr {$r1 + $dr}] ; set c2 [expr {$c1 + $dc}]
if {[info exists bd($r2,$c2)] == 0 || $bd($r2,$c2) != $you} continue
set r3 [expr {$r2 + $dr}] ; set c3 [expr {$c2 + $dc}]
if {[info exists bd($r3,$c3)] == 0 || $bd($r3,$c3) != $me} {
if {$st(rules) == "pente"} continue
if {[info exists bd($r3,$c3)] == 0 || $bd($r3,$c3) != $you} continue
set r4 [expr {$r3 + $dr}] ; set c4 [expr {$c3 + $dc}]
if {[info exists bd($r4,$c4)] == 0 || $bd($r4,$c4) != $me} continue
set bd($r3,$c3) 0
undraw_pip $r3 $c3
lappend undo [list $r3 $c3]
incr cnt3
}
set bd($r1,$c1) 0
undraw_pip $r1 $c1
set bd($r2,$c2) 0
undraw_pip $r2 $c2
incr cnt
lappend undo [list $r1 $c1] [list $r2 $c2]
}
return [concat $cnt $cnt3 $undo]
}
##+##########################################################################
#
# check_win - Checks to see if anyone has won
#
proc check_win {r c me} {
global bd st
if {$bd($r,$c) != $me} { return 0 }
foreach {dr dc} {0 1 1 1 1 0 1 -1} {
foreach {n pips} [adjacents $r $c $dr $dc] {}
if {$n < 5} continue
return [list 1 $pips]
}
if {$st(rules) == "pente" && $st(capt,$me) >= 5} { return 2 }
if {$st(capt,sum,$me) >= 15} { return 3 }
return 0
}
##+##########################################################################
#
# adjacents - Returns a list of all pips of the same color to row,col
# in the line dr, dc.
#
proc adjacents {r c dr dc} {
global bd
set which "p_${r}_$c" ;# Matches in dr,dc dir
set who $bd($r,$c)
for {set rr $r; set cc $c} {1} {} {
set rr [expr {$rr + $dr}] ; set cc [expr {$cc + $dc}]
if {[info exists bd($rr,$cc)] == 0 || $bd($rr,$cc) != $who} break
lappend which p_${rr}_$cc
}
for {set rr $r; set cc $c} {1} {} {
set rr [expr {$rr - $dr}] ; set cc [expr {$cc - $dc}]
if {[info exists bd($rr,$cc)] == 0 || $bd($rr,$cc) != $who} break
lappend which p_${rr}_$cc
}
return [list [llength $which] $which]
}
##+##########################################################################
#
# undo - Undoes the last move
# {r c captures 3captures {capture pips 1} {capture pips2}}
#
proc undo {} {
global st bd cl
undarken_all ;# Undo victory signs
set st(v) 0
set st(msg) ""
change_turn ;# Back to prev. turn
set me $st(t)
set you [expr {-$me}]
set cl2 $cl($you)
set w ".p[expr {(3 - $me) / 2}]" ;# Which window
set event [lindex $st(undo) 0] ;# Event to undo
set st(undo) [lrange $st(undo) 1 end]
foreach {r c cnt cnt3} $event break
if {$r != -999} {
set bd($r,$c) 0 ;# Remove pip from board
undraw_pip $r $c
foreach c [lrange $event 4 end] { ;# Undo capture events
foreach {rr cc} $c {}
set bd($rr,$cc) $you
draw_pip $rr $cc $cl2 pip$you ;# Draw the pip here
}
}
if {$cnt > 0} { ;# Undo any captures
incr st(capt,sum,$me) [expr {-2 * $cnt - $cnt3}]
while {[incr cnt -1] >= 0} {
$w delete pip$st(capt,$me) ;# Undraw capture on sidebar
incr st(capt,$me) -1
}
}
;# Update the cross hairs
set e [lindex "$st(undo) {0 0}" 0]
draw_cross_hairs [lindex $e 0] [lindex $e 1]
draw_turn_number [incr st(n) -1] ;# Go back a turn
if {$st(undo) == ""} {
.bundo config -state disabled
.m.game.m entryconfigure 3 -state disabled
}
}
proc help {} {
catch {destroy .help}
toplevel .help
wm transient .help .
wm title .help "TkPente Help"
if {[regexp {(\+[0-9]+)(\+[0-9]+)$} [wm geom .] => wx wy]} {
wm geom .help "+[expr {$wx+35}]+[expr {$wy+35}]"
}
set w .help.t
text $w -wrap word -width 70 -height 31 -pady 10 -padx 5
button .help.quit -text Dismiss -command {catch {destroy .help}}
pack .help.quit -side bottom
pack $w -side top -fill both -expand 1
$w tag config header -justify center -font bold -foreground red
$w tag config header2 -justify center -font bold
set margin [font measure [$w cget -font] " o "]
set margin2 [font measure [$w cget -font] " o - "]
$w tag config bullet -lmargin2 $margin
$w tag config bullet -font "[font actual [$w cget -font]] -weight bold"
$w tag config n -lmargin1 $margin -lmargin2 $margin
$w insert end "TkPente" header "\nby Keith Vetter\n\n" header2
set m "Pente, or Five-in-a-row type games are very old. In Japan "
append m "they have been played on a Go board for over a thousand years. "
append m "Pente was introduced to US in the late seventies and added a "
append m "twist to the general five-in-a-row idea: the ability to capture "
append m "opponent pieces.\n\n"
$w insert end "Overview\n" bullet $m n
set m "You win by either getting five (or more) stones in a row, "
append m "horizontally, vertically, or diagonally, with no empty points "
append m "between them, or by capturing five (or more) pairs of your "
append m "opponent's stones.\n\n"
$w insert end "Object of the Game\n" bullet $m n
set m "Players alternate turns, with the first player starting in the "
append m "middle. To balance the first player's slight advantage of "
append m "going first, his second move is restricted to be at least "
append m "two places of the center. If a move results in a capture, the "
append m "captured pieces are removed from the board.\n\n"
$w insert end "How to Play\n" bullet $m n
set m "If placing your piece results in two adjacent pieces of your "
append m "opponents being bracketed by your pieces, your opponent's "
append m "pieces are captured and removed from the board. Note, a single "
append m "move can result in multiple captures.\n\n"
$w insert end "Captures\n" bullet $m n
set m "Introduced in 1983, Keryo Pente is now perhaps the \"preferred\" "
append m "way to play pente. In Keryo Pente all normal rules apply except "
append m "that 1) triple captures are also allowed and 2) you need to "
append m "15 of your opponents pieces to win."
$w insert end "Keryo Pente\n" bullet $m n
$w config -state disabled
}
##+##########################################################################
#############################################################################
init ;# One time initialization
draw_menus
draw_board ;# Draw the board
draw_side ;# And the capture side bars
draw_buttons ;# And the buttons
new_game ;# Begin the game
