Last active
September 12, 2017 00:37
-
-
Save ohga/44c9dfca70b30211755b903f3842d96d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -Nurb -i --strip-trailing-cr -Nur a/shogi-server/bin/run.sample b/shogi-server/bin/run.sample | |
--- a/shogi-server/bin/run.sample 1970-01-01 09:00:00.000000000 +0900 | |
+++ b/shogi-server/bin/run.sample 2017-07-06 11:34:36.893489555 +0900 | |
@@ -0,0 +1,45 @@ | |
+#!/bin/bash | |
+# nohup sh ./run test01 0 3 test01 > /dev/null 2>&1 & | |
+ | |
+if [ $# -ne 4 ]; then | |
+ echo 'param error' | |
+ echo '{this script} game-tag lifetime countdown username' | |
+ exit 1 | |
+fi | |
+ | |
+# {任意文字列}-{持ち時間}-{秒読み(フィッシャークロックの場合は末尾にF)} | |
+# 例 test01-900-10 | |
+# 'test01' という名前で持ち時間15分 秒読みが10秒 | |
+## 時間切れが頻繁に発生する場合、エンジンの方のマージンと、gamename の秒読みを増やす、等で回避すること。 | |
+## YaneuraOu の場合、test-0-8, NetworkDelay2=2620 で T3 くらいになる。 | |
+## ので、ここで + 5 をして、 NetworkDelay2=26200 を与えている。 | |
+GAMENAME=$1-$2-$(($3 + 5)) | |
+ | |
+# この接続を識別する為の一意な名前とパスワード | |
+USER=$4 | |
+PASS=$4 | |
+ | |
+ENGINE=~/YaneuraOu-by-gcc | |
+ENGINE_OPT1="EvalDir=/opt/_eval/elmo_wcsc27,BookFile=no_book,NetworkDelay2=2620" | |
+ENGINE_OPT2="Threads=2,Hash=128,Ponder=true,MultiPV=1" | |
+ENGINE_OPT3="MaxMovesToDraw=256,EnteringKingRule=CSARule27" | |
+ | |
+ | |
+USITOCSA=~/shogi-server/bin/usiToCsa.rb | |
+HOST=127.0.0.1 | |
+EXT_OPT="--keep-alive=60 --info-ex --log-file=${USER}-$$.log" | |
+ | |
+while true; do | |
+ RAND=`od -vAn -N8 -tu8 < /dev/urandom | tr -d "[:space:]"`; | |
+ SLEEP_TIME=$((${RAND} % 8)); | |
+ | |
+ ${USITOCSA} --host ${HOST} --gamename=${GAMENAME} ${EXT_OPT} \ | |
+ --options "${ENGINE_OPT1},${ENGINE_OPT2},${ENGINE_OPT3}" \ | |
+ --id=${USER}@${RAND} --password=${PASS} ${ENGINE}; | |
+ | |
+ echo ""; | |
+ echo "sleep ${SLEEP_TIME}.."; | |
+ sleep ${SLEEP_TIME}; | |
+done; | |
+ | |
+ | |
diff -Nurb -i --strip-trailing-cr -Nur a/shogi-server/bin/usiToCsa.rb b/shogi-server/bin/usiToCsa.rb | |
--- a/shogi-server/bin/usiToCsa.rb 2017-07-11 14:49:05.349857170 +0900 | |
+++ b/shogi-server/bin/usiToCsa.rb 2017-07-06 11:34:36.893489555 +0900 | |
@@ -60,8 +60,8 @@ | |
keep-alive | |
Interval in seconds to send a keep-alive packet to the server. [default 0] | |
Disabled if it is 0. | |
- log-dir | |
- directory to put log files | |
+ log-file | |
+ log file. [default 'main.log'] | |
margin-msec | |
margin time [milliseconds] for byoyomi | |
options | |
@@ -72,6 +72,10 @@ | |
password for a CSA server | |
ponder | |
enble ponder | |
+ info-ex | |
+ enable to send extra information to the server with principal validation. | |
+ Ex. depth 26 seldepth 29 time 242045 nodes 16518672 nps 68246... | |
+ (NOTE) This isn't officially approved. | |
port | |
a port number to connect to a CSA server. 4081 is often used. | |
@@ -100,11 +104,12 @@ | |
["--host", GetoptLong::REQUIRED_ARGUMENT], | |
["--id", GetoptLong::REQUIRED_ARGUMENT], | |
["--keep-alive", GetoptLong::REQUIRED_ARGUMENT], | |
- ["--log-dir", GetoptLong::REQUIRED_ARGUMENT], | |
+ ["--log-file", GetoptLong::REQUIRED_ARGUMENT], | |
["--margin-msec", GetoptLong::REQUIRED_ARGUMENT], | |
["--options", GetoptLong::REQUIRED_ARGUMENT], | |
["--password", GetoptLong::REQUIRED_ARGUMENT], | |
["--ponder", GetoptLong::NO_ARGUMENT], | |
+ ["--info-ex", GetoptLong::NO_ARGUMENT], | |
["--port", GetoptLong::REQUIRED_ARGUMENT]) | |
parser.quiet = true | |
begin | |
@@ -124,12 +129,14 @@ | |
options[:hash] = options[:hash].to_i | |
options[:host] ||= ENV["HOST"] || "wdoor.c.u-tokyo.ac.jp" | |
options[:margin_msec] ||= ENV["MARGIN_MSEC"] || 2500 | |
+ options[:margin_msec] = options[:margin_msec].to_i | |
options[:id] ||= ENV["ID"] | |
options[:keep_alive] ||= ENV["KEEP_ALIVE"] || 0 | |
options[:keep_alive] = options[:keep_alive].to_i | |
- options[:log_dir] ||= ENV["LOG_DIR"] || "." | |
+ options[:log_file] ||= ENV["LOG_FILE"] || "main.log" | |
options[:password] ||= ENV["PASSWORD"] | |
options[:ponder] ||= ENV["PONDER"] || false | |
+ options[:info_ex] ||= ENV["INFO_EX"] || false | |
options[:port] ||= ENV["PORT"] || 4081 | |
options[:port] = options[:port].to_i | |
@@ -224,11 +231,13 @@ | |
@black_time = nil # milliseconds | |
@white_time = nil # milliseconds | |
@byoyomi = nil # milliseconds | |
+ @increment = 0 # milliseconds (increment非対応のshogi-serverとの互換性のために初期値は0にしておく) | |
@depth = nil | |
@cp = nil | |
@pv = nil | |
@ponder_move = nil | |
+ @info_ex = "" | |
end | |
def next_turn | |
@@ -236,6 +245,7 @@ | |
@cp = nil | |
@pv = nil | |
@ponder_move = nil | |
+ @info_ex = "" | |
end | |
def update_last_server_send_time | |
@@ -287,6 +297,7 @@ | |
end | |
def parse_game_summary(str) | |
+ bname = wname = "" | |
str.each_line do |line| | |
case line.strip | |
when /^Your_Turn:([\+\-])/ | |
@@ -301,7 +312,22 @@ | |
@white_time = $1.to_i * 1000 | |
when /^Byoyomi:(\d+)/ | |
@byoyomi = $1.to_i * 1000 | |
+ when /^Increment:(\d+)/ | |
+ @increment = $1.to_i * 1000 | |
+ when /^Name\+:(.+)/ | |
+ bname = $1.split("@")[0] | |
+ when /^Name\-:(.+)/ | |
+ wname = $1.split("@")[0] | |
+ when /^([\+\-]\d{4}\w{2}),T(\d+)/ | |
+ set_one_move(line) | |
+ end | |
end | |
+ | |
+ name = $options[:id].split("@")[0] | |
+ if (@side == true and name == wname) or (@side == false and name == bname)then | |
+ server_puts "REJECT" | |
+ transite :GAME_END | |
+ throw "Bad game summary: " + 'cansel...:' + name + ":" + str | |
end | |
if [@side, @black_time, @white_time, @byoyomi].include?(nil) | |
@@ -331,14 +357,20 @@ | |
case str | |
when /^START:(.*)/ | |
@game_id = $1 | |
+ @time_turn_start = Time.now | |
log_info "game crated #@game_id" | |
next_turn | |
engine_puts "usinewgame" | |
if @side | |
- engine_puts "position startpos" | |
+ engine_puts "position startpos moves #{@csaToUsi.usi_moves.join(" ")}" | |
+ if @increment > 0 then | |
+ engine_puts "go btime #@black_time wtime #@white_time binc #@increment winc #@increment" | |
+ else | |
engine_puts "go btime #@black_time wtime #@white_time byoyomi #{byoyomi()}" | |
end | |
+ | |
+ end | |
transite :GAME_CSA | |
when /^REJECT:(.*)/ | |
log_info "game rejected." | |
@@ -383,7 +415,11 @@ | |
# Trigger the next turn | |
transite :GAME_CSA | |
next_turn | |
+ if @increment > 0 then | |
+ engine_puts "position startpos moves #{@csaToUsi.usi_moves.join(" ")}\ngo btime #@black_time wtime #@white_time binc #@increment winc #@increment" | |
+ else | |
engine_puts "position startpos moves #{@csaToUsi.usi_moves.join(" ")}\ngo btime #@black_time wtime #@white_time byoyomi #{byoyomi()}" | |
+ end | |
else | |
case str | |
when /^(.*)\s+ponder\s+(.*)/ | |
@@ -395,7 +431,19 @@ | |
if $options[:ponder] | |
moves = @usiToCsa.usi_moves.clone | |
moves << @ponder_move | |
- engine_puts "position startpos moves #{moves.join(" ")}\ngo ponder btime #@black_time wtime #@white_time byoyomi #{byoyomi()}" | |
+ btime_tmp = @black_time | |
+ wtime_tmp = @white_time | |
+ estimated_consumption = (Time.now - @time_turn_start).ceil * 1000 # give a some margin by ceiling the value | |
+ if @side then | |
+ btime_tmp = [btime_tmp + @increment - estimated_consumption, 0].max | |
+ else | |
+ wtime_tmp = [wtime_tmp + @increment - estimated_consumption, 0].max | |
+ end | |
+ if @increment > 0 then | |
+ engine_puts "position startpos moves #{moves.join(" ")}\ngo ponder btime #{btime_tmp} wtime #{wtime_tmp} binc #@increment winc #@increment" | |
+ else | |
+ engine_puts "position startpos moves #{moves.join(" ")}\ngo ponder btime #{btime_tmp} wtime #{wtime_tmp} byoyomi #{byoyomi()}" | |
+ end | |
transite :PONDERING | |
end | |
else | |
@@ -404,21 +452,62 @@ | |
end | |
when /^info\s+(.*)/ | |
str = $1 | |
- if /depth\s(\d+)/ =~ str | |
- @depth = $1 | |
+ if /(\s+|^)depth\s(\d+)/ =~ str | |
+ @depth = $2 | |
+ end | |
+ if /(\s+|^)score\s+cp\s+(-?\d+)/ =~ str | |
+ @cp = $2.to_i | |
+ if !@side | |
+ @cp *= -1 | |
end | |
- if /score\s+cp\s+(\d+)/ =~ str | |
- @cp = $1.to_i | |
+ elsif /(\s+|^)score\s+mate\s+(-?\d+)/ =~ str | |
+ @cp = ($2.to_i < 0 ? -100000 : 100000) + $2.to_i # ex. mate 5 --> 100005 | |
if !@side | |
@cp *= -1 | |
end | |
end | |
- if /pv\s+(.*)$/ =~str | |
- @pv = $1 | |
+ if /(.*)(\s+|^)pv\s+(.*)$/ =~str | |
+ @info_ex = $1 if $options[:info_ex] | |
+ @pv = $3 | |
end | |
end | |
end | |
+ def set_one_move(str) | |
+ return if str.nil? || str.strip.empty? | |
+ log_server_recv str | |
+ | |
+ case str.strip | |
+ when /^%TORYO,T(\d+)/ | |
+ log_info str | |
+ when /^#(\w+)/ | |
+ s = $1 | |
+ log_info str | |
+ if %w!WIN LOSE DRAW CENSORED!.include?(s) | |
+ server_puts "LOGOUT" | |
+ engine_puts "gameover #{s.downcase}" | |
+ transite :GAME_END | |
+ end | |
+ when /^([\+\-]\d{4}\w{2}),T(\d+)/ | |
+ csa = $1 | |
+ msec = $2.to_i * 1000 | |
+ | |
+ if csa[0..0] == "+" | |
+ @black_time = [@black_time + @increment - msec, 0].max | |
+ if !@side | |
+ @time_turn_start = Time.now | |
+ end | |
+ else | |
+ @white_time = [@white_time + @increment - msec, 0].max | |
+ if @side | |
+ @time_turn_start = Time.now | |
+ end | |
+ end | |
+ state1, usi = @csaToUsi.next(csa) | |
+ state2, dummy = @usiToCsa.next(usi) | |
+ end | |
+ end | |
+ | |
def event_server_recv | |
unless [:GAME_CSA, :PONDERING].include?(@state) | |
throw "Bad state at event_engine_recv: #@state" | |
@@ -434,7 +523,7 @@ | |
when /^#(\w+)/ | |
s = $1 | |
log_info str | |
- if %w!WIN LOSE DRAW!.include?(s) | |
+ if %w!WIN LOSE DRAW CENSORED!.include?(s) | |
server_puts "LOGOUT" | |
engine_puts "gameover #{s.downcase}" | |
transite :GAME_END | |
@@ -444,9 +533,15 @@ | |
msec = $2.to_i * 1000 | |
if csa[0..0] == "+" | |
- @black_time = [@black_time - msec, 0].max | |
+ @black_time = [@black_time + @increment - msec, 0].max | |
+ if !@side | |
+ @time_turn_start = Time.now | |
+ end | |
else | |
- @white_time = [@white_time - msec, 0].max | |
+ @white_time = [@white_time + @increment - msec, 0].max | |
+ if @side | |
+ @time_turn_start = Time.now | |
+ end | |
end | |
state1, usi = @csaToUsi.next(csa) | |
@@ -461,7 +556,7 @@ | |
if usi == @ponder_move | |
engine_puts "ponderhit" | |
transite :GAME_CSA | |
- next_turn | |
+ #next_turn | |
# Engine keeps on thinking | |
else | |
engine_puts "stop" | |
@@ -469,11 +564,15 @@ | |
else | |
transite :GAME_CSA | |
next_turn | |
+ if @increment > 0 then | |
+ engine_puts "position startpos moves #{@csaToUsi.usi_moves.join(" ")}\ngo btime #@black_time wtime #@white_time binc #@increment winc #@increment" | |
+ else | |
engine_puts "position startpos moves #{@csaToUsi.usi_moves.join(" ")}\ngo btime #@black_time wtime #@white_time byoyomi #{byoyomi()}" | |
end | |
end | |
end | |
end | |
+ end | |
def comment | |
if [@depth, @cp, @pv].include?(nil) | |
@@ -496,10 +595,14 @@ | |
end | |
end | |
+ if @info_ex != "" | |
+ @info_ex = " ' " + @info_ex | |
+ end | |
+ | |
if moves.empty? | |
- return "" | |
+ return "'* #@cp#@info_ex" | |
else | |
- return "'* #@cp #{moves.join(" ")}" | |
+ return "'* #@cp #{moves.join(" ")}#@info_ex" | |
end | |
end | |
end # class BridgeState | |
@@ -631,10 +734,22 @@ | |
end | |
if $bridge_state.GAME_END? | |
+ engine_puts "quit" | |
log_info "game finished." | |
break | |
end | |
end | |
+ | |
+ if $engine.nil? | |
+ $engine.close | |
+ $engile = nil | |
+ end | |
+ | |
+ if $server.nil? | |
+ $server.close | |
+ $server = nil | |
+ end | |
+ | |
rescue Exception => ex | |
log_error "main: #{ex.class}: #{ex.message}\n\t#{ex.backtrace.join("\n\t")}" | |
end | |
@@ -642,12 +757,13 @@ | |
# MAIN | |
# | |
def main | |
- $logger = setup_logger("main.log") | |
# Parse command line options | |
$options = parse_command_line | |
check_command_line | |
+ $logger = setup_logger($options[:log_file]) | |
+ | |
# Start engine | |
start_engine | |
diff -Nurb -i --strip-trailing-cr -Nur a/shogi-server/mk_footer b/shogi-server/mk_footer | |
--- a/shogi-server/mk_footer 1970-01-01 09:00:00.000000000 +0900 | |
+++ b/shogi-server/mk_footer 2017-07-11 13:32:32.131562210 +0900 | |
@@ -0,0 +1,24 @@ | |
+#!/usr/bin/ruby | |
+ | |
+def main | |
+ printf("<table>\n"); | |
+ while line = $stdin.gets do | |
+ arr = line.split("\t") | |
+ if arr.count != 7 then | |
+ next | |
+ end | |
+ arr[3] = arr[3].split('@')[0] | |
+ arr[4] = arr[4].split('@')[0] | |
+ tmp_arr = arr[6].split("/") | |
+ arr[6] = tmp_arr.last().chop! | |
+ printf( | |
+ "<tr><td><a href=\"html/%s.html\">%s</a>(<a href=\"csa/%s\">csa</a>)</td>" + | |
+ "<td>%s</td><td>%s</td><td>%s</td><td>vs</td><td>%s</td><td>%s</td></tr>\n", | |
+ arr[6],arr[0],arr[6],arr[1],arr[2],arr[3],arr[4], arr[5]); | |
+ end | |
+ printf("</table>\n"); | |
+end | |
+ | |
+if __FILE__ == $0 | |
+ main | |
+end | |
diff -Nurb -i --strip-trailing-cr -Nur a/shogi-server/mk_html b/shogi-server/mk_html | |
--- a/shogi-server/mk_html 2017-07-11 14:49:05.349857170 +0900 | |
+++ b/shogi-server/mk_html 2017-07-11 13:33:19.939529677 +0900 | |
@@ -82,6 +82,9 @@ | |
def main | |
$wdoor = false | |
$footer_content = nil | |
+ $player_a = nil | |
+ $player_b = nil | |
+ $view_type = 0 | |
opts = OptionParser.new | |
opts.banner = "Usage: mk_html [OPTIONS]" | |
opts.on("--footer filename", String, "Insert contents of the filename at the bottom of a genrated page") do |filename| | |
@@ -92,6 +95,20 @@ | |
$footer_content = File.open(filename).read | |
end | |
opts.on("-w","--wdoor", "adopt a wdoor style") { $wdoor=true } | |
+ | |
+ opts.on("--player_a player_a", String, "player a") do |player_a| | |
+ $player_a = player_a | |
+ $view_type = 1 | |
+ end | |
+ opts.on("--player_b player_b", String, "player b") do |player_b| | |
+ if $player_a == nil | |
+ $stderr.puts "player_a is null." | |
+ raise | |
+ end | |
+ $player_b = player_b | |
+ $view_type = 2 | |
+ end | |
+ | |
opts.on_tail("-h", "--help", "show this message") do | |
puts opts | |
exit | |
@@ -149,6 +166,18 @@ | |
<% | |
win = yaml[key]['win'] | |
loss = yaml[key]['loss'] | |
+ case $view_type | |
+ when 0 then | |
+ win = yaml[key]['win'] | |
+ loss = yaml[key]['loss'] | |
+ when 1 then | |
+ win = yaml[key]['loss'] | |
+ loss = yaml[key]['win'] | |
+ when 2 then | |
+ win = yaml[key]['loss'] | |
+ loss = yaml[key]['win'] | |
+ end | |
+ | |
win_rate = win.to_f / (win + loss) | |
last_modified = yaml[key]['last_modified'] | |
@@ -166,13 +195,39 @@ | |
end | |
rate = yaml[key]['rate'] | |
+ # case $view_type | |
+ # when 0 then | |
+ # rate = yaml[key]['rate'] | |
+ # when 1 then | |
+ # rate = 0 | |
+ # when 2 then | |
+ # rate = 0 | |
+ # end | |
+ | |
top_rate ||= rate | |
diff_rate = rate - top_rate | |
diff_possibility = 1.0/(1.0 + 10**(-diff_rate/400.0)) | |
+ | |
+ ext_tag = '' | |
+ case yaml[key]['name'] | |
+ when $player_a then ext_tag = 'style="display:none"' | |
+ end | |
+ | |
+ key_link = yaml[key]['name'] + ".html" | |
+ case yaml[key]['name'] | |
+ when $player_a then | |
+ key_link = yaml[key]['name'] + ".html" | |
+ else | |
+ if $player_a != nil then | |
+ key_link = yaml[key]['name'] + "_vs_" + $player_a + ".html" | |
+ end | |
+ end | |
+ | |
%> | |
- <tr class="<%=player_decoration%>"> | |
+ <tr class="<%=player_decoration%>" <%=ext_tag%>> | |
<td class="name"> | |
- <a id="popup<%=popup_id+=1%>" href="/shogi/view/show-player.cgi?event=LATEST&filter=floodgate&show_self_play=1&user=<%=u key%>"><%= h yaml[key]['name'] %></a> | |
+ <%= ($view_type == 1 && yaml[key]['name'] != $player_a ) ? "vs " : "" %> | |
+ <a id="popup<%=popup_id+=1%>" href="<%= h key_link %>"><%= h yaml[key]['name'] %></a> | |
<script type="text/javascript"> | |
var tooltip<%=popup_id%> = new YAHOO.widget.Tooltip("myTooltip", { | |
context:"popup<%=popup_id%>", | |
@@ -220,7 +275,7 @@ | |
<html> | |
<head> | |
<title>Shogi Server Rating</title> | |
- <link rel="StyleSheet" type="text/css" href="http://wdoor.c.u-tokyo.ac.jp/shogi/shogi.css"> | |
+ <link rel="StyleSheet" type="text/css" href="html/shogi.css"> | |
<!-- CSS --> | |
<!-- License: http://developer.yahoo.com/yui/license.html --> | |
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.4.1/build/reset-fonts-grids/reset-fonts-grids.css"> | |
@@ -254,7 +309,7 @@ | |
<div id="hd"></div> | |
<div id="bd"> | |
-<h1>Shogi Server Rating</h1> | |
+<h1><a href=".">Shogi Server Rating</a></h1> | |
% tables.each_with_index do |t, index| | |
<table> | |
@@ -294,6 +349,7 @@ | |
<p>Groups are independently rated. You can not compare rates across them. | |
+ | |
<%= $footer_content %> | |
<hr/> | |
@@ -306,5 +362,6 @@ | |
</div> | |
</div></body> | |
+ | |
</html> | |
diff -Nurb -i --strip-trailing-cr -Nur a/shogi-server/mk_rate b/shogi-server/mk_rate | |
--- a/shogi-server/mk_rate 2017-07-11 14:49:05.349857170 +0900 | |
+++ b/shogi-server/mk_rate 2017-07-06 23:33:18.042062641 +0900 | |
@@ -869,11 +869,11 @@ | |
'win' => v[0], | |
'loss' => v[1]} | |
end | |
- unless validate(yaml) | |
- $stderr.puts "Aborted. It did not result in valid ratings." | |
- $stderr.puts yaml.to_yaml if $DEBUG | |
- exit 10 | |
- end | |
+# unless validate(yaml) | |
+# $stderr.puts "Aborted. It did not result in valid ratings." | |
+# $stderr.puts yaml.to_yaml if $DEBUG | |
+# exit 10 | |
+# end | |
puts yaml.to_yaml | |
end | |
diff -Nurb -i --strip-trailing-cr -Nur a/shogi-server/mk_view b/shogi-server/mk_view | |
--- a/shogi-server/mk_view 1970-01-01 09:00:00.000000000 +0900 | |
+++ b/shogi-server/mk_view 2017-07-11 13:33:39.731517490 +0900 | |
@@ -0,0 +1,78 @@ | |
+#!/usr/bin/ruby | |
+ | |
+require 'optparse' | |
+require 'erb' | |
+ | |
+include ERB::Util | |
+ | |
+def main | |
+ $csa_contents = nil | |
+ $svg_contents = nil | |
+ opts = OptionParser.new | |
+ opts.banner = "Usage: mk_view [OPTIONS]" | |
+ opts.on("--csa filename", String, "csa file") do |filename| | |
+ unless File.exist?(filename) | |
+ $stderr.puts "File not found: %s" % [filename] | |
+ raise | |
+ end | |
+ $csa_contents = File.open(filename).read | |
+ end | |
+ opts.on("--svg filename", String, "svg file") do |filename| | |
+ unless File.exist?(filename) | |
+ $stderr.puts "File not found: %s" % [filename] | |
+ raise | |
+ end | |
+ $svg_contents = File.open(filename).read | |
+ $svg_contents = $svg_contents[$svg_contents.index('<svg')..-1] | |
+ end | |
+ opts.on_tail("-h", "--help", "show this message") do | |
+ puts opts | |
+ exit | |
+ end | |
+ begin | |
+ opts.parse(ARGV) | |
+ rescue | |
+ puts opts | |
+ exit -1 | |
+ end | |
+ | |
+ erb = ERB.new( DATA.read, nil, "%>" ) | |
+ body = erb.result(binding) | |
+ puts body | |
+end | |
+ | |
+if __FILE__ == $0 | |
+ main | |
+end | |
+ | |
+__END__ | |
+<head> | |
+ <title></title> | |
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
+ <meta http-equiv="Content-Script-Type" content="text/javascript" /> | |
+ <meta http-equiv="Content-Style-Type" content="text/css" /> | |
+ <link rel="StyleSheet" type="text/css" href="shogi.css"> | |
+</head> | |
+<body> | |
+<pre id="csa" class="hidden"> | |
+<%= $csa_contents %> | |
+</pre> | |
+<table><tr><td><div id="board" class="board"></div> | |
+<script type="text/javascript" src="shogi-common.js"></script> | |
+<script type="text/javascript" src="kifu.js"></script> | |
+<script type="text/javascript">makeBoard('board', 'csa' , 'last')</script> | |
+</td> | |
+</tr> | |
+<tr> | |
+<td> | |
+<div style="text-align: center" class="graph"> | |
+<%= $svg_contents %> | |
+</div> | |
+</td> | |
+</tr></table> | |
+ | |
+ | |
+<a href="http://dragonfruit.ddns.net/">dragonfruit shogi server</a>を参考に | |
+<a href="http://www.sodan.org/~penny/shogi/kifu.html">棋譜再生用 Javascript</a>を利用しました | |
+ | |
+</body></html> | |
diff -Nurb -i --strip-trailing-cr -Nur a/shogi-server/shogi-server b/shogi-server/shogi-server | |
--- a/shogi-server/shogi-server 2017-07-11 14:49:05.349857170 +0900 | |
+++ b/shogi-server/shogi-server 2017-07-11 13:49:52.643436688 +0900 | |
@@ -97,6 +97,8 @@ | |
--player-log-dir dir | |
enable to log network messages for players. Log files | |
will be put in the dir. | |
+ --random-startpos-file | |
+ startpos sfen data | |
EXAMPLES | |
@@ -211,7 +213,8 @@ | |
["--max-identifier", GetoptLong::REQUIRED_ARGUMENT], | |
["--max-moves", GetoptLong::REQUIRED_ARGUMENT], | |
["--pid-file", GetoptLong::REQUIRED_ARGUMENT], | |
- ["--player-log-dir", GetoptLong::REQUIRED_ARGUMENT]) | |
+ ["--player-log-dir", GetoptLong::REQUIRED_ARGUMENT], | |
+ ["--random-startpos-file",GetoptLong::REQUIRED_ARGUMENT]) | |
parser.quiet = true | |
begin | |
parser.each_option do |name, arg| | |
@@ -422,6 +425,7 @@ | |
config[:Port] = port | |
config[:ServerType] = WEBrick::Daemon if $options["daemon"] | |
config[:Logger] = $logger | |
+ config[:MaxClients] = 1024 | |
setup_floodgate = nil | |
diff -Nurb -i --strip-trailing-cr -Nur a/shogi-server/shogi_server/command.rb b/shogi-server/shogi_server/command.rb | |
--- a/shogi-server/shogi_server/command.rb 2017-07-11 14:49:05.353857179 +0900 | |
+++ b/shogi-server/shogi_server/command.rb 2017-07-06 11:34:36.893489555 +0900 | |
@@ -561,9 +561,7 @@ | |
Game::new(@player.game_name, @player, rival, board) | |
end | |
else | |
- klass = Login.handicapped_game_name?(@game_name) || Board | |
- board = klass.new | |
- board.initial | |
+ board = set_random_startpos() | |
Game::new(@player.game_name, @player, rival, board) | |
end | |
else # rival not found | |
@@ -579,6 +577,50 @@ | |
end | |
return :continue | |
end | |
+ | |
+ def set_random_startpos() | |
+ | |
+ filename = $options["random-startpos-file"] | |
+ if filename == nil | |
+ klass = Login.handicapped_game_name?(@game_name) || Board | |
+ board = klass.new | |
+ board.initial | |
+ return board | |
+ end | |
+ | |
+ board = Board.new | |
+ | |
+ startpos = "" | |
+ File.open(filename) do |file| | |
+ line_cnt = rand(file.count) | |
+ | |
+ file.seek(0, IO::SEEK_SET) | |
+ file.each_line.with_index(1) do |line,nn| | |
+ if nn == line_cnt | |
+ startpos = line | |
+ break | |
+ end | |
+ end | |
+ end | |
+ | |
+ log_message("Floodgate: random_startpos choice #{startpos} from #{filename}.") | |
+ | |
+ usiToCsa = ShogiServer::Usi::UsiToCsa.new | |
+ moves = [] | |
+ startpos.split(/\s/).each do |usi| | |
+ begin | |
+ state, csa = usiToCsa.next(usi) | |
+ moves << csa | |
+ rescue | |
+ # ignore | |
+ end | |
+ end | |
+ # pp moves | |
+ | |
+ board.set_from_moves(moves) | |
+ return board | |
+ end | |
+ | |
end | |
# Command of CHAT | |
バイナリーファイル a/shogi-server/view_pack.tar.gz とb/shogi-server/view_pack.tar.gz は異なります |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment