Recursion TCL:避免在长时间递归计算期间出现超时/无响应窗口

Recursion TCL:避免在长时间递归计算期间出现超时/无响应窗口,recursion,timeout,tcl,Recursion,Timeout,Tcl,我已经编写了一个脚本,它将递归调用proc,直到实现一个解决方案。问题是我的愿望窗口同时变得没有响应。它不是打印我为日志记录添加的puts语句。我知道脚本在计算中很忙,但为什么put没有打印到stdout 如何在如此长的递归过程调用期间保持脚本/愿望窗口的活动状态。以下是完整的脚本 namespace eval chainReactionGlobal { #variable state [list 0 0 0 0 0 0 0 0 0] variable pos [lis

我已经编写了一个脚本,它将递归调用proc,直到实现一个解决方案。问题是我的愿望窗口同时变得没有响应。它不是打印我为日志记录添加的puts语句。我知道脚本在计算中很忙,但为什么put没有打印到stdout

如何在如此长的递归过程调用期间保持脚本/愿望窗口的活动状态。以下是完整的脚本

namespace eval chainReactionGlobal {
    #variable state  [list 0 0 0 0 0 0 0 0 0]
    variable pos     [list 0 1 2 3 4 5 6 7 8]
    variable posMax  [list 1 2 1 2 3 2 1 2 1]
    variable burstPos [list {1 3} {0 2 4} {1 5} {0 4 6} {1 3 5 7} {2 4 8} {3 7} {4 6 8} {5 7}]
    variable players [list A B C]
    variable boxLen   3
    variable boxWidth 3
}

proc ShowGraphicalState {state} {
    set length $chainReactionGlobal::boxLen
    set width $chainReactionGlobal::boxWidth
    puts "\n"
    puts "--------------------"
    puts -nonewline "\| [lindex $state 0][string repeat " " [expr 4-[string length [lindex $state 0]]]]\|"
    puts -nonewline "\| [lindex $state 1][string repeat " " [expr 4-[string length [lindex $state 1]]]]\|"
    puts -nonewline "\| [lindex $state 2][string repeat " " [expr 4-[string length [lindex $state 2]]]]\|"
    puts "\n--------------------"
    puts -nonewline "\| [lindex $state 3][string repeat " " [expr 4-[string length [lindex $state 3]]]]\|"
    puts -nonewline "\| [lindex $state 4][string repeat " " [expr 4-[string length [lindex $state 4]]]]\|"
    puts -nonewline "\| [lindex $state 5][string repeat " " [expr 4-[string length [lindex $state 5]]]]\|"
    puts "\n--------------------"
    puts -nonewline "\| [lindex $state 6][string repeat " " [expr 4-[string length [lindex $state 6]]]]\|"
    puts -nonewline "\| [lindex $state 7][string repeat " " [expr 4-[string length [lindex $state 7]]]]\|"
    puts -nonewline "\| [lindex $state 8][string repeat " " [expr 4-[string length [lindex $state 8]]]]\|"
    puts "\n--------------------"
}

proc GetNextPlayer {currentPlayer} {
    set currIdx [lsearch $chainReactionGlobal::players $currentPlayer]
    if {[expr $currIdx+1]<[llength $chainReactionGlobal::players ]} {
        return [lindex $chainReactionGlobal::players [expr $currIdx+1]]
    } else {
        return  [lindex $chainReactionGlobal::players 0]
    }    
}

# ------------------------------------------------------------------------
# This function will take input of a stable state and current player, will
# return list of possible unstable state the current player can make.
# ------------------------------------------------------------------------
proc GetPossibleStateMatrix {stableState currentPlayer} {
    array set stateList {}

    foreach position $chainReactionGlobal::pos {

        set localState $stableState
        set currentPosValue [lindex $localState $position]  
        if {$currentPosValue=="0"} {
            lset localState $position [string repeat $currentPlayer 1]
        set stateList($position) $localState
        } elseif {[regexp -all $currentPlayer $currentPosValue]>0} {
            lset localState $position $currentPosValue$currentPlayer
            set stateList($position) $localState
        }


    }

    return [array get stateList]
}



proc GetStabilizedState {unstableState impactPosList} {
    set isStable 0
    set affectedPosList {}
    while {!$isStable} {
        foreach position $impactPosList {
            set posValue [lindex $unstableState $position]
            if { $posValue=="0"} {
                    set posLength 0
            } else {
                set posLength [string length $posValue]
            }
            set posMaxLength [lindex $chainReactionGlobal::posMax $position]

            if {($posLength>$posMaxLength)} {
                if {[expr $posLength-$posMaxLength-1] > 0} {
                    lset unstableState $position [string repeat [string range $posValue 0 0] [expr [expr $posLength-$posMaxLength]-1]]
                } else {
                    lset unstableState $position "0"
                }

                foreach affectedPos [lindex $chainReactionGlobal::burstPos $position] {
                    set affectedPosValue [lindex $unstableState $affectedPos]
                    if { $affectedPosValue =="0"} {
                        set affectedPosValueLength 0
                    } else {
                        set affectedPosValueLength [string length $affectedPosValue]
                    }
                    set affectedPosMaxLength [lindex $chainReactionGlobal::posMax $affectedPos]

                    if {[expr $affectedPosValueLength+1]>$affectedPosMaxLength } {
                        if {[lsearch $affectedPosList $affectedPos ] ==-1} {
                            lappend affectedPosList $affectedPos 
                        }
                    }
                    lset unstableState $affectedPos [string repeat [string range $posValue 0 0] [expr 1+$affectedPosValueLength]]      
                }
            }
        }

        set isStable 1
        foreach position $chainReactionGlobal::pos {
            set posValue [lindex $unstableState $position]
        if { $posValue=="0"} {
                set posLength 0
        } else {
            set posLength [string length $posValue]
        }
        set posMaxLength [lindex $chainReactionGlobal::posMax $position]
            if {($posLength>$posMaxLength) && ($posValue!="0")} {
                set isStable 0
            }
        }

        if {$isStable==1} { 
            return $unstableState
        }
        set impactPosList $affectedPosList
    }

}


proc IsImmediateWin {state currentPlayer} {
    foreach elem $state {
        if {$elem==0} {
            continue
        } elseif {[regexp $currentPlayer $elem]} {
            continue
        } else {
            return 0
        }
    }
    return 1
}

    proc GetWinRatio {state myPlayer currentPlayer {test 0}} {

        puts "test $test state $state  myPlayer  $myPlayer currentPlayer $currentPlayer"

        set loss 0
        set win 0
        set possibleStateList [GetPossibleStateMatrix $state $currentPlayer]
        array set possibleStateArr $possibleStateList
        # puts possibleStateList$possibleStateList
        foreach possiblePos [lsort [array names possibleStateArr]] {
            set possibleState $possibleStateArr($possiblePos)
            puts "possibleState ----> $possibleState                          possiblePos  $possiblePos"
            set stableState [GetStabilizedState $possibleState $possiblePos]
            puts "stableState ----> $stableState"


            if {[IsImmediateWin $stableState $currentPlayer]} {
                if {$currentPlayer==$myPlayer } {
                    incr win
                } else {
                    incr loss
                }
            } else {
            puts "not immediate win"

                 set result [GetWinRatio $stableState $myPlayer [GetNextPlayer $currentPlayer] [expr $test+1] ]
                # set result "0:0"
                set winRes [lindex [split $result ":"] 0]
                set lossRes [lindex [split $result ":"] 1]

                incr win $winRes
                incr loss $lossRes
            }
            # puts "state [ShowGraphicalState $stableState]   wins:$win loss:$loss"

        }
        return ${win}:${loss}
    }
    puts "[GetWinRatio [list A CC A A B B A B C] A A]"    
namespace eval chainReactionGlobal{
#变量状态[列表0]
可变位置[列表01 2 3 4 5 6 7 8]
变量posMax[列表1 2 3 2 1 2 1]
变量burstPos[list{1 3}{0 2 4}{1 5}{0 4 6}{1 3 5 7}{2 4 8}{3 7}{4 6 8}{5 7}]
可变玩家[列表A B C]
可变boxLen 3
可变箱宽3
}
proc ShowGraphicalState{state}{
设置长度$chainReactionGlobal::boxLen
设置宽度$chainReactionGlobal::boxWidth
放入“\n”
放入“---------------”
puts-nonewline“\\\[lindex$state 0][string repeat”“[expr 4-[string length[lindex$state 0]]]]]\\\\\\124;”
puts-nonewline“\\\[lindex$state 1][string repeat”“[expr 4-[string length[lindex$state 1]]]]”
puts-nonewline“\\\[lindex$state 2][string repeat”“[expr 4-[string length[lindex$state 2]]]]\\\\\124;”
放置“\n------------------”
puts-nonewline“\\\[lindex$state 3][string repeat”“[expr 4-[string length[lindex$state 3]]]]”
puts-nonewline“\\\[lindex$state 4][string repeat”“[expr 4-[string length[lindex$state 4]]]]”
puts-nonewline“\\\[lindex$state 5][string repeat”“[expr 4-[string length[lindex$state 5]]]]]”
放置“\n------------------”
puts-nonewline“\\\[lindex$state 6][string repeat”“[expr 4-[string length[lindex$state 6]]]]]”
puts-nonewline“\\\[lindex$state 7][string repeat”“[expr 4-[string length[lindex$state 7]]]]]”
puts-nonewline“\\\[lindex$state 8][string repeat”“[expr 4-[string length[lindex$state 8]]]]]\\\\\\124;”
放置“\n------------------”
}
proc GetNextPlayer{currentPlayer}{
设置currIdx[lsearch$chainReactionGlobal::players$currentPlayer]
如果{[expr$currIdx+1]0}{
lset localState$position$currentPosValue$currentPlayer
设置状态列表($position)$localState
}
}
返回[数组获取状态列表]
}
proc GetStabilizedState{unstableState impactPosList}{
设置表0
set affectedPosList{}
而{!$isStable}{
foreach职位$impactPosList{
设置posValue[lindex$unstableState$position]
如果{$posValue==“0”}{
将posLength设置为0
}否则{
设置posLength[字符串长度$posValue]
}
设置posMaxLength[lindex$chainReactionGlobal::posMax$position]
如果{($posLength>$posMaxLength)}{
如果{[expr$posLength-$posMaxLength-1]>0}{
lset unstableState$position[字符串重复[string range$posValue 0][expr[expr$posLength-$posMaxLength]-1]]
}否则{
lset不稳定状态$位置“0”
}
foreach affectedPos[lindex$chainReactionGlobal::burstPos$position]{
设置affectedPosValue[lindex$unstableState$affectedPos]
如果{$affectedPosValue==“0”}{
将affectedPosValueLength设置为0
}否则{
设置affectedPosValueLength[字符串长度$affectedPosValue]
}
设置affectedPosMaxLength[lindex$chainReactionGlobal::posMax$affectedPos]
如果{[expr$affectedPosValueLength+1]>$affectedPosMaxLength}{
如果{[lsearch$affectedPosList$affectedPos]==-1}{
lappend affectedPosList$affectedPos
}
}
lset unstableState$affectedPos[字符串重复[string range$posValue 0][expr 1+$affectedPosValueLength]]
}
}
}
设置为表1
foreach职位$chainReactionGlobal::pos{
设置posValue[lindex$unstableState$position]
如果{$posValue==“0”}{
将posLength设置为0
}否则{
设置posLength[字符串长度$posValue]
}
设置posMaxLength[lindex$chainReactionGlobal::posMax$position]
如果{($posLength>$posMaxLength)&&($posValue!=“0”)}{
设置表0
}
}
如果{$isStable==1}{
返回$unstableState
}
设置impactPosList$affectedPosList
}
}
进程immediatewin{state currentPlayer}{
foreach elem$状态{
如果{$elem==0}{
持续
}elseif{[regexp$currentPlayer$elem]}{
持续
}否则{
返回0
}
}
返回1
}
proc GetWinRatio{state myPlayer currentPlayer{test 0}{
将“测试$测试状态$状态myPlayer$myPlayer currentPlayer$currentPlayer”
设置损失为0
设胜0
set-possibleStateList[GetPossibleStateMatrix$state$currentPlayer]
数组集possibleStateArr$possibleStateList
#puts possibleStateList$possibleStateList
foreach-possiblePos[lsort[数组名possiblestearr]]{
设置可能属性$可能属性参数($可能属性参数)
放置“possibleState-->$possibleState possiblePos$possiblePos”
设置稳定状态[GetStabilizedState$possibleState$possiblePos]
放入“stableState-->$stableState”
如果{[IsImmediateWin$stableState$currentPlayer]}{
如果{$currentPlayer==$myPlayer}{
增量赢
}否则{
增量损失
}
for {set i 0} {$i < 10000} {incr i} {puts $i}
for {set i 0} {$i < 10000} {incr i} {puts $i; update}
proc GetWinRatio {state myPlayer currentPlayer {test 0}} {

    puts "test $test state $state  myPlayer  $myPlayer currentPlayer $currentPlayer"
    update
    . . .