标签:
这次文章主要引用了网上的这篇教学http://www.cwflynt.com/TclForTeens/
步骤a 下载第17课里提到的扑克图像包
http://www.cwflynt.com/TclForTeens/cards.zip
解压缩cards.zip内所有文件到c:\cards\目录下
【你可以放在桌面的cards目录里,随意】
步骤b 跳到第20课http://www.cwflynt.com/TclForTeens/lsn20.html
找到最后一段框起来的源代码,它的上一句是“And that‘s all the changes. Here‘s the complete game.”
把这段框起来的代码复制到如下go代码的字符串常量里
package main
import "github.com/nsf/gothic"
const init_script = `
#init_script字符串常量,tcl/tk代码从下一行开始
`
func main() {
ir := gothic.NewInterpreter(init_script)
<-ir.Done
}
步骤c 保存go文件到c:\cards\目录下
【总之和图像文件在一起、同一目录就行】
步骤d 运行和编译
liteide下编译如下图

运行效果如下图:

步骤e 发行
从ActiveTcl 开发环境的安装目录(一般都是c:\tcl\)下找到
bin文件夹,把里面的tcl86.dll tk86.dll和zlib1.dll这3个文件复制到
c:\cards\目录下
再从c:\tcl\lib下找到tcl8.6和tk8.6文件夹,把这俩也复制到
c:\cards\lib\下
【如果必要可以删除一些用不上的包以减少发布文件的大小】
【完】
【附上全部go源代码,只有400多行,其中含tcl/tk代码的#注释都快有100行了】
package main
import "github.com/nsf/gothic"
const init_script = `
################################################################
# proc loadImages {}--
# Load the card images
# Arguments
# NONE
#
# Results
# The global array "concentration" is modified to include a
# list of card image names
#
proc loadImages {} {
global concentration
# The card image fileNames are named as S_V.gif where
# S is a single letter for suit (Hearts, Diamonds, Spades, Clubs)
# V is a 1 or 2 character descriptor of the suit - one of:
# a k q j 10 9 8 7 6 5 4 3 2
#
# glob returns a list of fileNames that match the pattern - *_*.gif
# means all fileNames that have a underbar in the name, and a .gif extension.
foreach fileName [glob *_*.gif] {
# We discard the aces to leave 48 cards because that makes a
# 6x8 card display.
if {($fileName ne "c_a.gif") &&
($fileName ne "h_a.gif") &&
($fileName ne "d_a.gif") &&
($fileName ne "s_a.gif")} {
# split the card name (c_8) from the suffix (.gif)
set card [lindex [split $fileName .] 0]
# Create an image with the card name, using the file
# and save it in a list of card images: concentration(cards)
image create photo $card -file $fileName
lappend concentration(cards) $card
}
}
# Load the images to use for the card back and
# for blank cards
foreach fileName {blank.gif back.gif} {
# split the card name from the suffix (.gif)
set card [lindex [split $fileName .] 0]
# Create the image
image create photo $card -file $fileName
}
}
################################################################
# proc randomizeList {}--
# Change the order of the cards in the list
# Arguments
# originalList The list to be shuffled
#
# Results
# The concentration(cards) list is changed - no cards will be lost
# of added, but the order will be random.
#
proc randomizeList {originalList} {
# How many cards are we playing with.
set listLength [llength $originalList]
# Initialize a new (random) list to be empty
set newList {}
# Loop for as many cards as are in the card list at the
# start. We remove one card on each pass through the loop.
for {set i $listLength} {$i > 0} {incr i -1} {
# Select a random card from the remaining cards.
set p1 [expr int(rand() * $i)]
# Put that card onto the new list of cards
lappend newList [lindex $originalList $p1]
# Remove that card from the card list.
set originalList [lreplace $originalList $p1 $p1]
}
# Replace the empty list of cards with the new list that‘s got all
# the cards in it.
return $newList
}
################################################################
# proc makeGameBoard {}--
# Create the game board widgets - canvas and labels.
# Arguments
# NONE
#
# Results
# New GUI widgets are created.
#
proc makeGameBoard {} {
# Create and grid the canvas that will hold the card images
canvas .game -width 800 -height 724 -bg gray
grid .game -row 1 -column 1 -columnspan 6
# Create and grid the labels for turns and score
label .lmyScoreLabel -text "My Score"
label .lmyScore -textvariable concentration(player,score)
label .lturnLabel -text "Turn"
label .lturn -textvariable concentration(turn)
grid .lmyScoreLabel -row 0 -column 1 -sticky e
grid .lmyScore -row 0 -column 2 -sticky w
grid .lturnLabel -row 0 -column 5 -sticky e
grid .lturn -row 0 -column 6 -sticky w
}
################################################################
# proc startGame {}--
# Actually start a game running
# Arguments
# NONE
#
# Results
# initializes per-game indices in the global array "concentration"
# The card list is randomized
# The GUI is modified.
#
proc startGame {} {
global concentration
set concentration(player,score) 0
set concentration(turn) 0
set concentration(selected,rank) {}
set concentration(player,x) 0
set concentration(player,y) 2
set concentration(cards) [randomizeList $concentration(cards)]
# Save the height and width of the cards to make the code easier
# to read.
set height [image height [lindex $concentration(cards) 0]]
set width [image width [lindex $concentration(cards) 0]]
# Leave spaces between cards.
incr width
incr height
# Remove any existing items on the canvas
.game delete all
# Start in the upper left hand corner
set x 90
set y 2
# Step through the list of cards
for {set pos 0} {$pos < [llength $concentration(cards)]} {incr pos} {
# Place the back-of-a-card image on the board
# to simulate a card that is face-down.
.game create image $x $y -image back -anchor nw -tag card_$pos
# Add a binding on the card back to react
# to a player left-clicking the back.
.game bind card_$pos <ButtonRelease-1> "playerTurn $pos"
# Step to the next column (the width of a card)
incr x $width
# If we‘ve put up 8 columns of cards, reset X to the
# far left, and step down one row.
if {$x >= [expr 90 + ($width * 8)] } {
set x 90
incr y $height
}
}
}
################################################################
# proc flipImageX {canvas canvasID start end background}--
# Makes it appear that an image object on a canvas is being flipped
# Arguments
# canvas The canvas holding the image
# canvasID The identifier for this canvas item
# start The initial image being displayed
# end The final image to display
# background The color to show behind the image being flipped.
# This is probably the canvas background color
#
# Results
# configuration for the canvas item is modified.
#
proc flipImageX {canvas canvasID start end background} {
global concentration
# Get the height/width of the image we‘ll be using
set height [image height $start]
set width [image width $start]
# The image will rotate around the X axis
# Calculate and save the center, since we‘ll be using it a lot
set centerX [expr $width / 2]
# Create a new temp image that we‘ll be modifying.
image create photo temp -height $height -width $width
# Copy the initial image into our temp image, and configure the
# canvas to show our temp image, instead of the original image
# in this location.
temp copy $start
$canvas itemconfigure $canvasID -image temp
update idle
after 25
# copy the start image into the temp with greater
# subsampling (making it appear like more and more of an
# edge view of the image).
# Move the start of the image to the center on each pass
# through the loop
for {set i 2} {$i < 8} {incr i} {
set left [expr $centerX - $width / (2 * $i)]
set right [expr $centerX + $width / (2 * $i)]
temp put $background -to 0 0 $width $height
temp copy -to $left 0 $right $height -subsample $i 1 $start
update idle
after 10
}
# copy the end image into the temp with less and less
# subsampling (making it appear like less and less of an
# edge view of the image).
# Move the start of the image away from thecenter on each pass
# through the loop
for {set i 8} {$i > 1} {incr i -1} {
set left [expr $centerX - $width / (2 * $i)]
set right [expr $centerX + $width / (2 * $i)]
temp put $background -to 0 0 $width $height
temp copy -to $left 0 $right $height -subsample $i 1 $end
update idle
after 10
}
# configure the canvas to show the final image, and
# delete our temporary image
$canvas itemconfigure $canvasID -image $end
image delete temp
}
################################################################
# proc playerTurn {position}--
# Selects a card for comparison, or checks the current
# card against a previous selection.
# Arguments
# position The position of this card in the deck.
#
# Results
# The selection fields of the global array "concentration"
# are modified.
# The GUI is modified.
#
proc playerTurn {position} {
global concentration
set card [lindex $concentration(cards) $position]
flipImageX .game card_$position back $card gray
set rank [lindex [split $card _] 1]
# If concentration(selected,rank) is empty, this is the first
# part of a turn. Mark this card as selected and we‘re done.
if {{} eq $concentration(selected,rank)} {
# Increment the turn counter
incr concentration(turn)
set concentration(selected,rank) $rank
set concentration(selected,position) $position
set concentration(selected,card) $card
} else {
# If we‘re here, then this is the second part of a turn.
# Compare the rank of this card to the previously saved rank.
if {$position == $concentration(selected,position)} {
return
}
# Update the screen *NOW* (to show the card), and pause for one second.
update idle
after 1000
# If the ranks are identical, handle the match condition
if {$rank eq $concentration(selected,rank)} {
# Increase the score by one
incr concentration(player,score)
# Remove the two cards and their backs from the board
.game bind card_$position <ButtonRelease-1> ""
.game bind card_$concentration(selected,position) <ButtonRelease-1> ""
moveCards card_$position card_$concentration(selected,position) player
# Check to see if we‘ve won yet.
if {[checkForFinished]} {
endGame
}
} else {
# If we‘re here, the cards were not a match.
# flip the cards to back up (turn the cards face down)
flipImageX .game card_$position $card back gray
flipImageX .game card_$concentration(selected,position) $concentration(selected,card) back gray
}
# Whether or not we had a match, reset the concentration(selected,rank)
# to an empty string so that the next click will be a select.
set concentration(selected,rank) {}
}
}
################################################################
# proc moveCards {cvs id1 id2 prefix}--
# moves Cards from their current location to the
# score pile for
# Arguments
# id1 An identifier for a canvas item
# id2 An identifier for a canvas item
# prefix Identifier for which location should get the card
#
# Results
#
#
proc moveCards {id1 id2 prefix} {
global concentration
.game raise $id1
.game raise $id2
.game coords $id1 $concentration($prefix,x) $concentration($prefix,y)
.game coords $id2 $concentration($prefix,x) $concentration($prefix,y)
incr concentration($prefix,y) 30
}
################################################################
# proc checkForFinished {}--
# checks to see if the game is won. Returns true/false
# Arguments
#
#
# Results
#
#
proc checkForFinished {} {
global concentration
global concentration
if {$concentration(player,score) == 24} {
return TRUE
} else {
return FALSE
}
}
################################################################
# proc endGame {}--
# Provide end of game display and ask about a new game
# Arguments
# NONE
#
# Results
# GUI is modified
#
proc endGame {} {
global concentration
set position 0
foreach card $concentration(cards) {
.game itemconfigure card_$position -image $card
incr position
}
# Update the screen *NOW*, and pause for 2 seconds
update idle;
after 2000
.game create rectangle 250 250 450 400 -fill blue -stipple gray50 -width 3 -outline gray
button .again -text "Play Again" -command {
destroy .again
destroy .quit
startGame
}
button .quit -text "Quit" -command "exit"
.game create window 350 300 -window .again
.game create window 350 350 -window .quit
}
loadImages
makeGameBoard
startGame
`
func main() {
ir := gothic.NewInterpreter(init_script)
<-ir.Done
}
把别人的Tcl/Tk代码加入到Go语言里15 游戏8 翻牌游戏
标签:
原文地址:http://my.oschina.net/tsl/blog/414583