diff --git a/web/cdb.php b/web/cdb.php index ee90cc8..5dda20f 100644 --- a/web/cdb.php +++ b/web/cdb.php @@ -768,7 +768,7 @@ function getMovesWithCheck( $redis, $row, $ply, $enumlimit, $resetlimit, $learn, } return $moves1; } -function getAnalysisPath( $redis, $row, $ply, $enumlimit, $isbest, $learn, $depth, &$pv ) { +function getAnalysisPath( $redis, $row, $ply, $enumlimit, $isbest, $learn, $depth, &$pv, $stable ) { list( $moves1, $finals ) = getAllScores( $redis, $row ); $BWfen = cbgetBWfen( $row ); @@ -833,8 +833,53 @@ function getAnalysisPath( $redis, $row, $ply, $enumlimit, $isbest, $learn, $dept $moves2[ $key ] = $item; } } - shuffle_assoc( $moves2 ); - arsort( $moves2 ); + if( !$stable ) + { + shuffle_assoc( $moves2 ); + arsort( $moves2 ); + } + else + { + $moves3 = array(); + foreach( $moves2 as $key => $item ) { + $moves3[ $key ][0] = 0; + $moves3[ $key ][1] = 0; + if( isset( $finals[ $key ] ) ) + continue; + $nextfen = cbmovemake( $row, $key ); + list( $nextmoves, $variations ) = getMoves( $redis, $nextfen, false, false, $depth ); + if( count( $nextmoves ) > 0 ) { + arsort( $nextmoves ); + $nextscore = reset( $nextmoves ); + $throttle = getthrottle( $nextscore ); + $nextsum = 0; + $nextcount = 0; + $totalvalue = 0; + foreach( $nextmoves as $record => $score ) { + if( $score >= $throttle ) { + $nextcount++; + $nextsum = $nextsum + $score; + $totalvalue = $totalvalue + $nextsum; + } + else + break; + } + $moves3[ $key ][0] = count( $nextmoves ); + $moves3[ $key ][1] = $nextcount; + } + } + uksort( $moves2, function ( $a, $b ) use ( $moves2, $moves3 ) { + if( $moves2[$a] != $moves2[$b] ) { + return $moves2[$b] - $moves2[$a]; + } else if( $moves3[$a][1] != $moves3[$b][1] ) { + return $moves3[$a][1] - $moves3[$b][1]; + } else if( $moves3[$a][0] != $moves3[$b][0] ) { + return $moves3[$b][0] - $moves3[$a][0]; + } else { + return $a - $b; + } + } ); + } foreach( $moves2 as $key => $item ) { $GLOBALS['counter']++; if( $isbest ) { @@ -847,7 +892,7 @@ function getAnalysisPath( $redis, $row, $ply, $enumlimit, $isbest, $learn, $dept $nextfen = cbmovemake( $row, $key ); $GLOBALS['historytt'][$current_hash]['fen'] = $nextfen; $GLOBALS['historytt'][$current_hash]['move'] = $key; - $nextmoves = getAnalysisPath( $redis, $nextfen, $ply + 1, $enumlimit, $isbest, false, $depth, $pv ); + $nextmoves = getAnalysisPath( $redis, $nextfen, $ply + 1, $enumlimit, $isbest, false, $depth, $pv, $stable ); $isbest = false; unset( $GLOBALS['historytt'][$current_hash] ); if( isset( $GLOBALS['loopcheck'] ) ) { @@ -1767,8 +1812,12 @@ function is_true( $val ) { uksort( $statmoves, function ( $a, $b ) use ( $statmoves, $variations ) { if( $statmoves[$a] != $statmoves[$b] ) { return $statmoves[$b] - $statmoves[$a]; - } else { + } else if( $variations[$a][1] != $variations[$b][1] ) { return $variations[$a][1] - $variations[$b][1]; + } else if( $variations[$a][0] != $variations[$b][0] ) { + return $variations[$b][0] - $variations[$a][0]; + } else { + return $a - $b; } } ); $maxscore = reset( $statmoves ); @@ -2016,11 +2065,17 @@ function is_true( $val ) { } else if( $action == 'querypv' ) { $pv = array(); + if( isset( $_REQUEST['stable'] ) ) { + $stable = is_true( $_REQUEST['stable'] ); + } + else { + $stable = false; + } $GLOBALS['counter'] = 0; $GLOBALS['boardtt'] = new Judy( Judy::STRING_TO_INT ); $redis = new Redis(); $redis->pconnect('192.168.1.2', 8888, 1.0); - $statmoves = getAnalysisPath( $redis, $row, 0, 200, true, $learn, 0, $pv ); + $statmoves = getAnalysisPath( $redis, $row, 0, 200, true, $learn, 0, $pv, $stable ); if( count( $statmoves ) > 0 ) { if( $isJson ) echo '"status":"ok","score":' . $statmoves[$pv[0]] . ',"depth":' . count( $pv ) . ',"pv":["' . implode( '","', $pv ) . '"],"pvSAN":["' . implode( '","', cbmovesan( $row, $pv ) ) . '"]'; diff --git a/web/chessdb.php b/web/chessdb.php index 14077e1..0f0eddf 100644 --- a/web/chessdb.php +++ b/web/chessdb.php @@ -1121,7 +1121,7 @@ function getMovesWithCheck( $redis, $row, $banmoves, $ply, $enumlimit, $resetlim } return $moves1; } -function getAnalysisPath( $redis, $row, $banmoves, $ply, $enumlimit, $isbest, $learn, $depth, &$pv ) { +function getAnalysisPath( $redis, $row, $banmoves, $ply, $enumlimit, $isbest, $learn, $depth, &$pv, $stable ) { list( $moves1, $finals ) = getAllScores( $redis, $row ); $LRfen = ccbgetLRfen( $row ); $BWfen = ccbgetBWfen( $row ); @@ -1236,8 +1236,53 @@ function getAnalysisPath( $redis, $row, $banmoves, $ply, $enumlimit, $isbest, $l $moves2[ $key ] = $item; } } - shuffle_assoc( $moves2 ); - arsort( $moves2 ); + if( !$stable ) + { + shuffle_assoc( $moves2 ); + arsort( $moves2 ); + } + else + { + $moves3 = array(); + foreach( $moves2 as $key => $item ) { + $moves3[ $key ][0] = 0; + $moves3[ $key ][1] = 0; + if( isset( $finals[ $key ] ) ) + continue; + $nextfen = ccbmovemake( $row, $key ); + list( $nextmoves, $variations ) = getMoves( $redis, $nextfen, array(), false, false, false, $depth ); + if( count( $nextmoves ) > 0 ) { + arsort( $nextmoves ); + $nextscore = reset( $nextmoves ); + $throttle = getthrottle( $nextscore ); + $nextsum = 0; + $nextcount = 0; + $totalvalue = 0; + foreach( $nextmoves as $record => $score ) { + if( $score >= $throttle ) { + $nextcount++; + $nextsum = $nextsum + $score; + $totalvalue = $totalvalue + $nextsum; + } + else + break; + } + $moves3[ $key ][0] = count( $nextmoves ); + $moves3[ $key ][1] = $nextcount; + } + } + uksort( $moves2, function ( $a, $b ) use ( $moves2, $moves3 ) { + if( $moves2[$a] != $moves2[$b] ) { + return $moves2[$b] - $moves2[$a]; + } else if( $moves3[$a][1] != $moves3[$b][1] ) { + return $moves3[$a][1] - $moves3[$b][1]; + } else if( $moves3[$a][0] != $moves3[$b][0] ) { + return $moves3[$b][0] - $moves3[$a][0]; + } else { + return $a - $b; + } + } ); + } foreach( $moves2 as $key => $item ) { $GLOBALS['counter']++; if( $isbest ) { @@ -1250,7 +1295,7 @@ function getAnalysisPath( $redis, $row, $banmoves, $ply, $enumlimit, $isbest, $l $nextfen = ccbmovemake( $row, $key ); $GLOBALS['historytt'][$current_hash]['fen'] = $nextfen; $GLOBALS['historytt'][$current_hash]['move'] = $key; - $nextmoves = getAnalysisPath( $redis, $nextfen, array(), $ply + 1, $enumlimit, $isbest, false, $depth, $pv ); + $nextmoves = getAnalysisPath( $redis, $nextfen, array(), $ply + 1, $enumlimit, $isbest, false, $depth, $pv, $stable ); $isbest = false; unset( $GLOBALS['historytt'][$current_hash] ); if( isset( $GLOBALS['loopcheck'] ) ) { @@ -2123,8 +2168,12 @@ function is_true( $val ) { uksort( $statmoves, function ( $a, $b ) use ( $statmoves, $variations ) { if( $statmoves[$a] != $statmoves[$b] ) { return $statmoves[$b] - $statmoves[$a]; - } else { + } else if( $variations[$a][1] != $variations[$b][1] ) { return $variations[$a][1] - $variations[$b][1]; + } else if( $variations[$a][0] != $variations[$b][0] ) { + return $variations[$b][0] - $variations[$a][0]; + } else { + return $a - $b; } } ); $maxscore = reset( $statmoves ); @@ -2275,11 +2324,17 @@ function is_true( $val ) { } else if( $action == 'querypv' ) { $pv = array(); + if( isset( $_REQUEST['stable'] ) ) { + $stable = is_true( $_REQUEST['stable'] ); + } + else { + $stable = false; + } $GLOBALS['counter'] = 0; $GLOBALS['boardtt'] = new Judy( Judy::STRING_TO_INT ); $redis = new Redis(); $redis->pconnect('192.168.1.2', 8889, 1.0); - $statmoves = getAnalysisPath( $redis, $row, $banmoves, 0, 200, true, $learn, 0, $pv ); + $statmoves = getAnalysisPath( $redis, $row, $banmoves, 0, 200, true, $learn, 0, $pv, $stable ); if( count( $statmoves ) > 0 ) { echo 'score:' . $statmoves[$pv[0]] . ',depth:' . count( $pv ) . ',pv:' . implode( '|', $pv ); } diff --git a/web/query/file/xiangqi.js b/web/query/file/xiangqi.js index f235eb9..528bd64 100644 --- a/web/query/file/xiangqi.js +++ b/web/query/file/xiangqi.js @@ -1140,7 +1140,7 @@ function ChangeFen(id) { return; } -function FillPV(id) { +function FillPV(id, stable) { if (busy) return; busy = 1; @@ -1152,7 +1152,7 @@ function FillPV(id) { var xmlhttpPV = getXmlHttp(); - xmlhttpPV.open('GET', apiurl + '?action=querypv&board=' + b[2], true); + xmlhttpPV.open('GET', apiurl + '?action=querypv&board=' + b[2] + "&stable=" + stable, true); xmlhttpPV.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttpPV.onreadystatechange = function() { if (xmlhttpPV.readyState == 4) { @@ -1185,7 +1185,7 @@ function FillPV(id) { function mclick(e, id) { e.preventDefault(); if (e.shiftKey) { - FillPV(id); + FillPV(id, true); } else { ChangeFen(id); @@ -1195,7 +1195,7 @@ function mclick(e, id) { function mcontext(e, id) { e.preventDefault(); - FillPV(id); + FillPV(id, e.shiftKey); return false; } diff --git a/web/query_en/file/xiangqi.js b/web/query_en/file/xiangqi.js index 5b8d70b..4246226 100644 --- a/web/query_en/file/xiangqi.js +++ b/web/query_en/file/xiangqi.js @@ -1140,7 +1140,7 @@ function ChangeFen(id) { return; } -function FillPV(id) { +function FillPV(id, stable) { if (busy) return; busy = 1; @@ -1152,7 +1152,7 @@ function FillPV(id) { var xmlhttpPV = getXmlHttp(); - xmlhttpPV.open('GET', apiurl + '?action=querypv&board=' + b[2], true); + xmlhttpPV.open('GET', apiurl + '?action=querypv&board=' + b[2] + "&stable=" + stable, true); xmlhttpPV.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttpPV.onreadystatechange = function() { if (xmlhttpPV.readyState == 4) { @@ -1185,7 +1185,7 @@ function FillPV(id) { function mclick(e, id) { e.preventDefault(); if (e.shiftKey) { - FillPV(id); + FillPV(id, true); } else { ChangeFen(id); @@ -1195,7 +1195,7 @@ function mclick(e, id) { function mcontext(e, id) { e.preventDefault(); - FillPV(id); + FillPV(id, e.shiftKey); return false; } diff --git a/web/queryc/file/cdb.js b/web/queryc/file/cdb.js index 2758049..d20b4f6 100644 --- a/web/queryc/file/cdb.js +++ b/web/queryc/file/cdb.js @@ -1033,7 +1033,7 @@ function Initialize2() { return; } -function FillPV(id) { +function FillPV(id, stable) { if (busy) return; busy = 1; @@ -1045,7 +1045,7 @@ function FillPV(id) { var xmlhttpPV = getXmlHttp(); - xmlhttpPV.open('GET', apiurl + '?action=querypv&board=' + b[2], true); + xmlhttpPV.open('GET', apiurl + '?action=querypv&board=' + b[2] + "&stable=" + stable, true); xmlhttpPV.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttpPV.onreadystatechange = function() { if (xmlhttpPV.readyState == 4) { @@ -1079,7 +1079,7 @@ function FillPV(id) { function mclick(e, id) { e.preventDefault(); if (e.shiftKey) { - FillPV(id); + FillPV(id, true); } else { ChangeFen(id); @@ -1089,7 +1089,7 @@ function mclick(e, id) { function mcontext(e, id) { e.preventDefault(); - FillPV(id); + FillPV(id, e.shiftKey); return false; } diff --git a/web/queryc_en/file/cdb.js b/web/queryc_en/file/cdb.js index b9a3d37..f9498eb 100644 --- a/web/queryc_en/file/cdb.js +++ b/web/queryc_en/file/cdb.js @@ -1033,7 +1033,7 @@ function Initialize2() { return; } -function FillPV(id) { +function FillPV(id, stable) { if (busy) return; busy = 1; @@ -1045,7 +1045,7 @@ function FillPV(id) { var xmlhttpPV = getXmlHttp(); - xmlhttpPV.open('GET', apiurl + '?action=querypv&board=' + b[2], true); + xmlhttpPV.open('GET', apiurl + '?action=querypv&board=' + b[2] + "&stable=" + stable, true); xmlhttpPV.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttpPV.onreadystatechange = function() { if (xmlhttpPV.readyState == 4) { @@ -1079,7 +1079,7 @@ function FillPV(id) { function mclick(e, id) { e.preventDefault(); if (e.shiftKey) { - FillPV(id); + FillPV(id, true); } else { ChangeFen(id); @@ -1089,7 +1089,7 @@ function mclick(e, id) { function mcontext(e, id) { e.preventDefault(); - FillPV(id); + FillPV(id, e.shiftKey); return false; }