package require Tk 8.5 for {set i 0} {$ i <64} {incr i} {lappend icells [expr {$ i / 8}] [expr {$ i% 8}]} array set vs [list 1 2 2 1 cl, 1 black cl, 2 white pn, 1 black pn, 2 white] ttk :: button .b1 -text "New game" -command {newgame 1 2} ttk :: button .b2 -text "Exit" -command {exit} ttk :: label .l1 -text "Welcome to Reversi game" canvas .cv -width 479 -height 479 grid rowconfigure. 1-weight 1 grid columnconfigure. 2-weight 1 grid .b1 .b2 .l1 -padx 4 -pady 4 -sticky e grid .cv -padx 4 -pady 4 -columnspan 3 foreach {xy} $ icells { set cr1 [list [expr {$ x * 60 + 2}] [expr {$ y * 60 + 2}] [expr {$ x * 60 + 60}] [expr {$ y * 60 + 60}]] set cr2 [list [expr {$ x * 60 + 4}] [expr {$ y * 60 + 4}] [expr {$ x * 60 + 58}] [expr {$ y * 60 + 58}]] .cv create rectangle $ cr1 -fill gray -tag "cell, $ x, $ y" .cv create oval $ cr2 -state hidden -tag "piece $ x, $ y" .cv bind cell, $ x, $ y <1> [list evuser $ x $ y]} proc pieceset {xyp} { .cv itemconfigure $ x, $ y -state normal -fill $ :: vs (cl, $ p) incr :: score ($ p) [expr {+ ($ :: board ($ x, $ y)! = $ p)}]] incr :: score ($ :: vs (p)) [expr {- ($ :: board ($ x, $ y) == $ $ vs ($ p))}] set :: board ($ x, $ y) [list $ p]} proc newgame {p1 p2} { .cv itemconfigure piece -state hidden array set :: score [list 0 0 1 0 2 0] array set :: player [list 1 $ p1 2 $ p2] foreach {xy} $ :: icells {set :: board ($ x, $ y) 0} foreach {xys} {3 3 2 4 4 2 3 4 1 4 3 1} {pieceset $ x $ y $ s} set :: cur 1; waitturn} proc getflips {xyp} { if {$ :: board ($ x, $ y)! = 0} return; set result {} foreach {ix iy} {0 -1 0 1 -1 0 1 0 -1 -1 1 1 1 1 -1 -1 1} { set temp {} for {set i [expr {$ x + $ ix}]; set j [expr {$ y + $ iy}]} \ {[info exists :: board ($ i, $ j)]} {incr i $ ix; incr j $ iy} { switch - $ :: board ($ i, $ j) \ $ :: vs ($ p) {lappend temp $ i $ j} \ $ p {foreach {mn} $ temp {lappend result $ m $ n}; break} \ 0 {break} }} return $ result} proc waitturn {} { .l1 configure -text "Go $ :: vs (pn, $ :: cur) ($ :: score (1): $ :: score (2))" array set v [list $ :: cur {} $ :: vs ($ :: cur) {}] foreach {xy} $ :: icells { set l [getflips $ x $ y $ :: cur]; if {[llength $ l]} {lappend v ($ :: cur) [list $ x $ y]} set l [getflips $ x $ y $ :: vs ($ :: cur)]; if {[llength $ l]} {lappend v ($ :: vs ($ :: cur)) [list $ x $ y]}} if {[llength $ v ($ :: cur)] == 0 && [llength $ v ($ :: vs ($ :: cur))] == 0} { tk_messageBox -title "Reversi" -message "Game over"; return} if {$ :: player ($ :: cur) == 1 && [llength $ v ($ :: cur)]} { set :: waituser 1; return} if {$ :: player ($ :: cur) == 2 && [llength $ v ($ :: cur)]} { set :: waituser 0 set :: flip [lindex $ v ($ :: cur) [expr {int ([llength $ v ($ :: cur)] * rand ())}]]] turn [lindex $ :: flip 0] [lindex $ :: flip 1] $ :: cur} set :: cur $ :: vs ($ :: cur); after idle waitturn} proc evuser {xy} { if {[info exists :: waituser] && $ :: waituser && [turn $ x $ y $ :: cur]} { set :: cur $ :: vs ($ :: cur); after idle waitturn}} proc turn {xyp} { set flips [getflips $ x $ y $ p] foreach {ij} $ flips {pieceset $ i $ j $ p} if {[llength $ flips]} {pieceset $ x $ y $ p; return 1} else {return 0}}
incr :: score ($ p) [expr {+ ($ :: board ($ x, $ y)! = $ p)}]] incr :: score ($ :: vs (p)) [expr {- ($ :: board ($ x, $ y) == $ :: vs ($ p))}].
Source: https://habr.com/ru/post/89822/
All Articles