AI Testing: AI batch testing scripts and web interface
This commit is contained in:
parent
f85264e315
commit
535fb6d8b0
5 changed files with 642 additions and 0 deletions
17
utils/ai_test/ai_test.cfg
Normal file
17
utils/ai_test/ai_test.cfg
Normal file
|
@ -0,0 +1,17 @@
|
|||
[default]
|
||||
path_to_wesnoth_binary=../../wesnoth-debug ../..
|
||||
arguments_to_wesnoth_binary=--log-info=ai/testing --nogui --multiplayer --controller1=ai --controller2=ai
|
||||
number_of_tests=10000
|
||||
ai_config1=ai/ais/formula_ai.cfg
|
||||
ai_config2=ai/ais/default_ai.cfg
|
||||
faction1=
|
||||
faction2=
|
||||
db_ip=127.0.0.1
|
||||
db_port=5432
|
||||
db_name=org.wesnoth.ai.test
|
||||
db_user=wesnoth_ai_test_user
|
||||
db_pass=PASSWORD
|
||||
map1=multiplayer_Weldyn_Channel
|
||||
map2=multiplayer_The_Freelands
|
||||
map3=multiplayer_Den_of_Onis
|
||||
map4=multiplayer_Fallenstar_Lake
|
185
utils/ai_test/ai_test.py
Executable file
185
utils/ai_test/ai_test.py
Executable file
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/env python
|
||||
from subprocess import Popen,PIPE
|
||||
from time import clock, time
|
||||
from pyPgSQL import PgSQL
|
||||
import ConfigParser
|
||||
import os
|
||||
import string
|
||||
import random
|
||||
|
||||
class GameResult:
|
||||
ai_config1 = ''
|
||||
ai_config2 = ''
|
||||
ai_ident1 = ''
|
||||
ai_ident2 = ''
|
||||
duration = '0'
|
||||
faction1 = ''
|
||||
faction2 = ''
|
||||
is_success = 'false'
|
||||
local_modifications = 'false'
|
||||
map = ''
|
||||
svn_release = '0'
|
||||
test = 'default'
|
||||
turn = '0'
|
||||
version_string = ''
|
||||
winner_side = '0'
|
||||
|
||||
def __init__(self,_ai_config1,_ai_config2,_faction1,_faction2,_map,_test):
|
||||
self.ai_config1 = _ai_config1
|
||||
self.ai_config2 = _ai_config2
|
||||
self.faction1 = _faction1
|
||||
self.faction2 = _faction2
|
||||
self.map = _map
|
||||
self.test = _test
|
||||
|
||||
def filter_non_printable(str):
|
||||
return ''.join(c for c in str if ord(c) > 31 or ord(c) == 9)
|
||||
|
||||
def construct_command_line(cfg,ai1,ai2,f1,f2,map):
|
||||
wesnoth = cfg.get('default','path_to_wesnoth_binary')
|
||||
options= cfg.get('default','arguments_to_wesnoth_binary')
|
||||
ai_config1='--ai_config1='+ai1
|
||||
ai_config2='--ai_config2='+ai2
|
||||
if (map==''):
|
||||
optmap=''
|
||||
else:
|
||||
optmap='--scenario='+map
|
||||
|
||||
return wesnoth+' '+options+' '+optmap+' '+ai_config1+' '+ai_config2
|
||||
|
||||
def do_filter(str,substring):
|
||||
n = str.find(substring)
|
||||
if (n>-1):
|
||||
return n,str[n+len(substring):].strip()
|
||||
return n,''
|
||||
|
||||
def run_game(cfg,game_result):
|
||||
|
||||
command_line = construct_command_line(cfg,game_result.ai_config1,game_result.ai_config2, game_result.faction1, game_result.faction2, game_result.map)
|
||||
print 'Running: '+command_line
|
||||
start = time()
|
||||
p = Popen(command_line, shell=True, stdout=PIPE, stderr=PIPE)
|
||||
outlines = p.stdout.readlines()
|
||||
outerrlines = p.stderr.readlines()
|
||||
print 'Finished'
|
||||
for line in outerrlines:
|
||||
str = filter_non_printable(line.strip())
|
||||
n,s = do_filter(str,'info ai/testing: WINNER:')
|
||||
if (n>-1):
|
||||
#print 'AND THE WINNER IS: '+s
|
||||
game_result.winner_side = s
|
||||
game_result.is_success = 'true'
|
||||
continue
|
||||
|
||||
n,s = do_filter(str,'info ai/testing: VERSION:')
|
||||
if (n>-1):
|
||||
#print 'AND THE VERSION IS: '+s
|
||||
game_result.version_string = s
|
||||
n1 = s.rfind('(')
|
||||
n2 = s.rfind(')')
|
||||
if ((n1>-1) and (n2>-1) and (n2>n1)):
|
||||
sz = s[n1+1:n2]
|
||||
#parse local_modifications
|
||||
#parse svn_release
|
||||
game_result.svn_release = sz
|
||||
continue
|
||||
|
||||
n,s = do_filter(str,'info ai/testing: VICTORY_TURN:')
|
||||
if (n>-1):
|
||||
#print 'AND THE VICTORY_TURN IS: '+s
|
||||
game_result.turn = s
|
||||
continue
|
||||
|
||||
n,s = do_filter(str,'info ai/testing: AI_IDENTIFIER1:')
|
||||
if (n>-1):
|
||||
#print 'AND THE AI_IDENTIFIER1 IS: '+s
|
||||
game_result.ai_ident1 = s.strip()
|
||||
continue
|
||||
|
||||
n,s = do_filter(str,'info ai/testing: AI_IDENTIFIER2:')
|
||||
if (n>-1):
|
||||
#print 'AND THE AI_IDENTIFIER2 IS: '+s
|
||||
game_result.ai_ident2 = s.strip()
|
||||
continue
|
||||
|
||||
n,s = do_filter(str,'info ai/testing: FACTION1:')
|
||||
if (n>-1):
|
||||
#print 'AND THE FACTION1 IS: '+s
|
||||
game_result.faction1 = s
|
||||
continue
|
||||
|
||||
n,s = do_filter(str,'info ai/testing: FACTION2:')
|
||||
if (n>-1):
|
||||
#print 'AND THE FACTION2 IS: '+s
|
||||
game_result.faction2 = s
|
||||
continue
|
||||
|
||||
game_result.duration = time() - start
|
||||
if (game_result.is_success=='false'):
|
||||
print 'Warning: not success!'
|
||||
print '===================='
|
||||
print 'stderr:'
|
||||
for line in outerrlines:
|
||||
print filter_non_printable(line.strip())
|
||||
print 'stdout:'
|
||||
for line in outlines:
|
||||
print filter_non_printable(line.strip())
|
||||
print '===================='
|
||||
|
||||
return game_result
|
||||
|
||||
def save_result(cfg,game_result):
|
||||
print 'Saving to DB....'
|
||||
query = 'insert into game(ai_config1,ai_config2,ai_ident1,ai_ident2,duration,faction1,faction2,is_success,local_modifications,map,svn_release,test,turn,version_string,winner_side) values (%s,%s,%s,%s,cast(%s as double precision),%s,%s,cast(%s as boolean),cast(%s as boolean),%s,cast(%s as int),%s,cast(%s as int),%s,cast(%s as int))'
|
||||
db_ip = cfg.get('default','db_ip')
|
||||
db_port = cfg.getint('default','db_port')
|
||||
db_name = cfg.get('default','db_name')
|
||||
db_user = cfg.get('default','db_user')
|
||||
db_pass = cfg.get('default','db_pass')
|
||||
|
||||
dbconnection = PgSQL.connect(database=db_name,host=db_ip,port=db_port,user=db_user,password=db_pass)
|
||||
cu = dbconnection.cursor()
|
||||
cu.execute(query, game_result.ai_config1, game_result.ai_config2, game_result.ai_ident1, game_result.ai_ident2, game_result.duration, game_result.faction1, game_result.faction2, game_result.is_success, game_result.local_modifications, game_result.map, game_result.svn_release, game_result.test, game_result.turn, game_result.version_string, game_result.winner_side)
|
||||
cu.execute('commit')
|
||||
dbconnection.close()
|
||||
print 'Saved to DB'
|
||||
|
||||
def maps(cfg):
|
||||
mp = 1
|
||||
while 1:
|
||||
try:
|
||||
yield cfg.get('default','map'+`mp`);
|
||||
mp= mp+1
|
||||
except:
|
||||
return
|
||||
|
||||
def tests(cfg):
|
||||
ai1=cfg.get('default','ai_config1').strip()
|
||||
ai2=cfg.get('default','ai_config2').strip()
|
||||
f1=cfg.get('default','faction1').strip()
|
||||
f2=cfg.get('default','faction2').strip()
|
||||
n=cfg.getint('default','number_of_tests')
|
||||
maplist = []
|
||||
for map in maps(cfg):
|
||||
maplist.append(map)
|
||||
random.seed()
|
||||
for i in range(0, n):
|
||||
map = random.choice(maplist)
|
||||
d = random.randint(0,1)
|
||||
print 'TEST: map '+map+' i='+str(i)+' d='+str(d)
|
||||
if (d==0):
|
||||
game_result = GameResult(ai1,ai2,f1,f2,map,'default')
|
||||
else:
|
||||
game_result = GameResult(ai2,ai1,f2,f1,map,'default')
|
||||
yield game_result
|
||||
|
||||
# main
|
||||
|
||||
cfg = ConfigParser.ConfigParser()
|
||||
cfg.read('ai_test.cfg')
|
||||
|
||||
for test in tests(cfg):
|
||||
game_result = run_game(cfg,test)
|
||||
save_result(cfg,game_result)
|
||||
|
||||
|
188
utils/ai_test/ai_test_db.backup
Normal file
188
utils/ai_test/ai_test_db.backup
Normal file
|
@ -0,0 +1,188 @@
|
|||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
-- Started on 2009-04-28 03:24:33 EEST
|
||||
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = off;
|
||||
SET check_function_bodies = false;
|
||||
SET client_min_messages = warning;
|
||||
SET escape_string_warning = off;
|
||||
|
||||
--
|
||||
-- TOC entry 296 (class 2612 OID 45054)
|
||||
-- Name: plpgsql; Type: PROCEDURAL LANGUAGE; Schema: -; Owner: pgsql
|
||||
--
|
||||
|
||||
CREATE PROCEDURAL LANGUAGE plpgsql;
|
||||
|
||||
|
||||
ALTER PROCEDURAL LANGUAGE plpgsql OWNER TO pgsql;
|
||||
|
||||
SET search_path = public, pg_catalog;
|
||||
|
||||
SET default_tablespace = '';
|
||||
|
||||
SET default_with_oids = false;
|
||||
|
||||
--
|
||||
-- TOC entry 1469 (class 1259 OID 44782)
|
||||
-- Dependencies: 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 6
|
||||
-- Name: game; Type: TABLE; Schema: public; Owner: wesnoth_ai_test_user; Tablespace:
|
||||
--
|
||||
|
||||
CREATE TABLE game (
|
||||
id bigint NOT NULL,
|
||||
svn_release integer DEFAULT 0 NOT NULL,
|
||||
datetime timestamp with time zone DEFAULT now() NOT NULL,
|
||||
winner_side integer DEFAULT 0 NOT NULL,
|
||||
ai_config1 text DEFAULT ''::text NOT NULL,
|
||||
ai_config2 text DEFAULT ''::text NOT NULL,
|
||||
local_modifications boolean DEFAULT false NOT NULL,
|
||||
turn integer DEFAULT 1 NOT NULL,
|
||||
ai_ident1 text DEFAULT ''::text NOT NULL,
|
||||
ai_ident2 text DEFAULT ''::text NOT NULL,
|
||||
is_success boolean DEFAULT true NOT NULL,
|
||||
version_string text DEFAULT ''::text NOT NULL,
|
||||
duration double precision DEFAULT 0 NOT NULL,
|
||||
map text DEFAULT ''::text NOT NULL,
|
||||
faction1 text DEFAULT ''::text NOT NULL,
|
||||
faction2 text DEFAULT ''::text NOT NULL,
|
||||
test text DEFAULT 'default'::text NOT NULL,
|
||||
CONSTRAINT winner_side_gte_0 CHECK ((winner_side >= 0))
|
||||
);
|
||||
|
||||
|
||||
ALTER TABLE public.game OWNER TO wesnoth_ai_test_user;
|
||||
|
||||
--
|
||||
-- TOC entry 1470 (class 1259 OID 45085)
|
||||
-- Dependencies: 1546 6
|
||||
-- Name: games_side; Type: VIEW; Schema: public; Owner: wesnoth_ai_test_user
|
||||
--
|
||||
|
||||
CREATE VIEW games_side AS
|
||||
SELECT game.id, game.svn_release, game.datetime, game.duration, game.map, 1 AS my_side, CASE WHEN (game.winner_side = 1) THEN 1 WHEN (game.winner_side = 2) THEN -1 ELSE 0 END AS outcome, CASE WHEN (game.winner_side = 1) THEN 1 ELSE 0 END AS win, CASE WHEN (game.winner_side = 0) THEN 1 ELSE 0 END AS draw, CASE WHEN (game.winner_side = 2) THEN 1 ELSE 0 END AS loss, CASE WHEN (game.winner_side = 1) THEN game.turn ELSE 0 END AS win_turns, CASE WHEN (game.winner_side = 2) THEN game.turn ELSE 0 END AS loss_turns, game.is_success, game.version_string, game.ai_config1 AS ai_config_me, game.ai_config2 AS ai_config_enemy, game.ai_ident1 AS ai_ident_me, game.ai_ident2 AS ai_ident_enemy, game.local_modifications, game.turn, game.faction1 AS faction_me, game.faction2 AS faction_enemy FROM game WHERE (game.svn_release <> 0) UNION SELECT game.id, game.svn_release, game.datetime, game.duration, game.map, 2 AS my_side, CASE WHEN (game.winner_side = 1) THEN -1 WHEN (game.winner_side = 2) THEN 1 ELSE 0 END AS outcome, CASE WHEN (game.winner_side = 2) THEN 1 ELSE 0 END AS win, CASE WHEN (game.winner_side = 0) THEN 1 ELSE 0 END AS draw, CASE WHEN (game.winner_side = 1) THEN 1 ELSE 0 END AS loss, CASE WHEN (game.winner_side = 2) THEN game.turn ELSE 0 END AS win_turns, CASE WHEN (game.winner_side = 1) THEN game.turn ELSE 0 END AS loss_turns, game.is_success, game.version_string, game.ai_config2 AS ai_config_me, game.ai_config1 AS ai_config_enemy, game.ai_ident2 AS ai_ident_me, game.ai_ident1 AS ai_ident_enemy, game.local_modifications, game.turn, game.faction1 AS faction_me, game.faction2 AS faction_enemy FROM game WHERE (game.svn_release <> 0);
|
||||
|
||||
|
||||
ALTER TABLE public.games_side OWNER TO wesnoth_ai_test_user;
|
||||
|
||||
--
|
||||
-- TOC entry 20 (class 1255 OID 45064)
|
||||
-- Dependencies: 296 6
|
||||
-- Name: avg_from(bigint, bigint); Type: FUNCTION; Schema: public; Owner: pgsql
|
||||
--
|
||||
|
||||
CREATE FUNCTION avg_from(bigint, bigint) RETURNS double precision
|
||||
AS $_$
|
||||
BEGIN
|
||||
IF $2=0 THEN
|
||||
RETURN 0;
|
||||
ELSE
|
||||
RETURN cast($1 as double precision)/$2;
|
||||
END IF;
|
||||
END;
|
||||
$_$
|
||||
LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
ALTER FUNCTION public.avg_from(bigint, bigint) OWNER TO pgsql;
|
||||
|
||||
--
|
||||
-- TOC entry 1468 (class 1259 OID 44780)
|
||||
-- Dependencies: 1469 6
|
||||
-- Name: game_id_seq; Type: SEQUENCE; Schema: public; Owner: wesnoth_ai_test_user
|
||||
--
|
||||
|
||||
CREATE SEQUENCE game_id_seq
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
ALTER TABLE public.game_id_seq OWNER TO wesnoth_ai_test_user;
|
||||
|
||||
--
|
||||
-- TOC entry 1765 (class 0 OID 0)
|
||||
-- Dependencies: 1468
|
||||
-- Name: game_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: wesnoth_ai_test_user
|
||||
--
|
||||
|
||||
ALTER SEQUENCE game_id_seq OWNED BY game.id;
|
||||
|
||||
|
||||
--
|
||||
-- TOC entry 1738 (class 2604 OID 44785)
|
||||
-- Dependencies: 1469 1468 1469
|
||||
-- Name: id; Type: DEFAULT; Schema: public; Owner: wesnoth_ai_test_user
|
||||
--
|
||||
|
||||
ALTER TABLE game ALTER COLUMN id SET DEFAULT nextval('game_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- TOC entry 1757 (class 2606 OID 44794)
|
||||
-- Dependencies: 1469 1469
|
||||
-- Name: pk_game; Type: CONSTRAINT; Schema: public; Owner: wesnoth_ai_test_user; Tablespace:
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY game
|
||||
ADD CONSTRAINT pk_game PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- TOC entry 1762 (class 0 OID 0)
|
||||
-- Dependencies: 6
|
||||
-- Name: public; Type: ACL; Schema: -; Owner: pgsql
|
||||
--
|
||||
|
||||
REVOKE ALL ON SCHEMA public FROM PUBLIC;
|
||||
REVOKE ALL ON SCHEMA public FROM pgsql;
|
||||
GRANT ALL ON SCHEMA public TO pgsql;
|
||||
GRANT ALL ON SCHEMA public TO PUBLIC;
|
||||
|
||||
|
||||
--
|
||||
-- TOC entry 1763 (class 0 OID 0)
|
||||
-- Dependencies: 1469
|
||||
-- Name: game; Type: ACL; Schema: public; Owner: wesnoth_ai_test_user
|
||||
--
|
||||
|
||||
REVOKE ALL ON TABLE game FROM PUBLIC;
|
||||
REVOKE ALL ON TABLE game FROM wesnoth_ai_test_user;
|
||||
GRANT ALL ON TABLE game TO wesnoth_ai_test_user;
|
||||
GRANT SELECT ON TABLE game TO wesnoth_ai_test_viewer;
|
||||
|
||||
|
||||
--
|
||||
-- TOC entry 1764 (class 0 OID 0)
|
||||
-- Dependencies: 1470
|
||||
-- Name: games_side; Type: ACL; Schema: public; Owner: wesnoth_ai_test_user
|
||||
--
|
||||
|
||||
REVOKE ALL ON TABLE games_side FROM PUBLIC;
|
||||
REVOKE ALL ON TABLE games_side FROM wesnoth_ai_test_user;
|
||||
GRANT ALL ON TABLE games_side TO wesnoth_ai_test_user;
|
||||
GRANT SELECT ON TABLE games_side TO wesnoth_ai_test_viewer;
|
||||
|
||||
|
||||
--
|
||||
-- TOC entry 1766 (class 0 OID 0)
|
||||
-- Dependencies: 1468
|
||||
-- Name: game_id_seq; Type: ACL; Schema: public; Owner: wesnoth_ai_test_user
|
||||
--
|
||||
|
||||
REVOKE ALL ON SEQUENCE game_id_seq FROM PUBLIC;
|
||||
REVOKE ALL ON SEQUENCE game_id_seq FROM wesnoth_ai_test_user;
|
||||
GRANT ALL ON SEQUENCE game_id_seq TO wesnoth_ai_test_user;
|
||||
GRANT SELECT ON SEQUENCE game_id_seq TO wesnoth_ai_test_viewer;
|
||||
|
||||
|
||||
-- Completed on 2009-04-28 03:24:36 EEST
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
49
utils/ai_test/readme.txt
Normal file
49
utils/ai_test/readme.txt
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
AI Batch testing suite
|
||||
Copyright (C) 2009 by Yurii Chernyi <terraninfo@terraninfo.net>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
REQUIRES:
|
||||
Wesnoth
|
||||
Postgresql database for storing data
|
||||
PHP-enabled web server for web frontend
|
||||
|
||||
INSTALLATION:
|
||||
|
||||
1. Create a role, two users and a database - one for uploader script with INSERT priv (and ability to use the sequence used for generating IDs), and another for web frontend with SELECT priv.
|
||||
---------------------
|
||||
CREATE ROLE wesnoth_ai_test_viewer
|
||||
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
|
||||
|
||||
CREATE ROLE wesnoth_ai_test_user LOGIN
|
||||
PASSWORD 'YOUR_PASSWORD_FOR_TEST_USER'
|
||||
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
|
||||
GRANT wesnoth_ai_test_viewer TO wesnoth_ai_test_user;
|
||||
|
||||
CREATE ROLE wesnoth_ai_test_viewer_impl LOGIN
|
||||
PASSWORD 'YOUR_PASSWORD_FOR_WEB_FRONTEND_USER'
|
||||
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
|
||||
GRANT wesnoth_ai_test_viewer TO wesnoth_ai_test_viewer_impl;
|
||||
|
||||
CREATE DATABASE "org.wesnoth.ai.test"
|
||||
WITH OWNER = wesnoth_ai_test_user
|
||||
ENCODING = 'UTF8';
|
||||
---------------------
|
||||
2. Restore ai_test_db.backup to that newly created DB to create the DB schema and set privilegies.
|
||||
|
||||
3. place wesnoth_ai_test.php at a php-enabled web server
|
||||
|
||||
4. Modify passwords/paths in ai_test.cfg and wesnoth_ai_test.php
|
||||
|
||||
|
||||
|
203
utils/ai_test/wesnoth_ai_test.php
Normal file
203
utils/ai_test/wesnoth_ai_test.php
Normal file
|
@ -0,0 +1,203 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Wesnoth AI Testing Statistics</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$database = pg_connect("host=127.0.0.1 dbname=org.wesnoth.ai.test user=wesnoth_ai_test_viewer_impl password=PASSWORD");
|
||||
if (!$database) {
|
||||
print("Connection Failed.");
|
||||
exit;
|
||||
} else {
|
||||
# print("Connection Ok!");
|
||||
}
|
||||
?>
|
||||
<h2>Latest svn AI wins % graph:</h2>
|
||||
<?php
|
||||
$query = "select ai_ident_me,avg_from(sum(win)*100,count(*))::bigint as win_percent from games_side where svn_release=(select max(svn_release) from games_side) group by ai_ident_me order by ai_ident_me;";
|
||||
$result = pg_query($query);
|
||||
if (!$result) {
|
||||
echo pg_last_error();
|
||||
exit();
|
||||
}
|
||||
$a = "";
|
||||
$b = "";
|
||||
$i = true;
|
||||
while($myrow = pg_fetch_assoc($result)) {
|
||||
if ($i) {
|
||||
$a=$a.$myrow['ai_ident_me'];
|
||||
$b=$b.$myrow['win_percent'];
|
||||
$i=false;
|
||||
} else {
|
||||
$a=$a."|".$myrow['ai_ident_me'];
|
||||
$b=$b.",".$myrow['win_percent'];
|
||||
}
|
||||
}
|
||||
|
||||
printf("<img src=\"http://chart.apis.google.com/chart?cht=p3&chd=t:$b&chs=500x200&chl=$a\" alt=\"win percentages\" title=\"win percentages\"");
|
||||
?>
|
||||
|
||||
<h2>By AI:</h2>
|
||||
<table border=1>
|
||||
<tr>
|
||||
<th>AI</th>
|
||||
<th>SVN Release</th>
|
||||
<th>Win %</th>
|
||||
<th>Games</th>
|
||||
<th>Wins</th>
|
||||
<th>Losses</th>
|
||||
<th>Avg. turns to win</th>
|
||||
<th>Avg. turns to lose</th>
|
||||
</tr>
|
||||
<?php
|
||||
$query = "select ai_ident_me, svn_release, avg_from(sum(win)*100,count(*)) as win_percent, count(*) as games, sum(win) as wins, sum(draw) as draws, sum(loss) as losses, avg_from(sum(win_turns),sum(win)) as avg_win_turns, avg_from(sum(loss_turns),sum(loss)) as avg_loss_turns from games_side group by ai_ident_me, svn_release order by ai_ident_me, svn_release desc;";
|
||||
$result = pg_query($query);
|
||||
if (!$result) {
|
||||
echo pg_last_error();
|
||||
exit();
|
||||
}
|
||||
|
||||
while($myrow = pg_fetch_assoc($result)) {
|
||||
printf ("<tr><td>%s</td><td>%d</td><td>%.1f</td><td>%d</td><td>%d</td><td>%d</td><td>%.1f</td><td>%.1f</td></tr>",
|
||||
$myrow['ai_ident_me'],$myrow['svn_release'],$myrow['win_percent'],$myrow['games'],$myrow['wins'],$myrow['losses'],$myrow['avg_win_turns'],$myrow['avg_loss_turns']);
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
<h2>By AI and side</h2>
|
||||
<table border=1>
|
||||
<tr>
|
||||
<th>AI</th>
|
||||
<th>Side</th>
|
||||
<th>SVN Release</th>
|
||||
<th>Win %</th>
|
||||
<th>Games</th>
|
||||
<th>Wins</th>
|
||||
<th>Losses</th>
|
||||
<th>Avg. turns to win</th>
|
||||
<th>Avg. turns to lose</th>
|
||||
</tr>
|
||||
<?php
|
||||
$query = "select ai_ident_me, my_side, svn_release, avg_from(sum(win)*100,count(*)) as win_percent, count(*) as games, sum(win) as wins, sum(draw) as draws, sum(loss) as losses, avg_from(sum(win_turns),sum(win)) as avg_win_turns, avg_from(sum(loss_turns),sum(loss)) as avg_loss_turns from games_side group by ai_ident_me, my_side, svn_release order by ai_ident_me, my_side, svn_release desc;";
|
||||
$result = pg_query($query);
|
||||
if (!$result) {
|
||||
echo pg_last_error();
|
||||
exit();
|
||||
}
|
||||
|
||||
while($myrow = pg_fetch_assoc($result)) {
|
||||
printf ("<tr><td>%s</td><td>%s</td><td>%d</td><td>%.1f</td><td>%d</td><td>%d</td><td>%d</td><td>%.1f</td><td>%.1f</td></tr>",
|
||||
$myrow['ai_ident_me'],$myrow['my_side'],$myrow['svn_release'],$myrow['win_percent'],$myrow['games'],$myrow['wins'],$myrow['losses'],$myrow['avg_win_turns'],$myrow['avg_loss_turns']);
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
<h2>By AI and map</h2>
|
||||
<table border=1>
|
||||
<tr>
|
||||
<th>AI</th>
|
||||
<th>Map</th>
|
||||
<th>SVN Release</th>
|
||||
<th>Win %</th>
|
||||
<th>Games</th>
|
||||
<th>Wins</th>
|
||||
<th>Losses</th>
|
||||
<th>Avg. turns to win</th>
|
||||
<th>Avg. turns to lose</th>
|
||||
</tr>
|
||||
<?php
|
||||
$query = "select ai_ident_me, map, svn_release, avg_from(sum(win)*100,count(*)) as win_percent, count(*) as games, sum(win) as wins, sum(draw) as draws, sum(loss) as losses, avg_from(sum(win_turns),sum(win)) as avg_win_turns, avg_from(sum(loss_turns),sum(loss)) as avg_loss_turns from games_side group by ai_ident_me, map, svn_release order by ai_ident_me, map, svn_release desc;";
|
||||
$result = pg_query($query);
|
||||
if (!$result) {
|
||||
echo pg_last_error();
|
||||
exit();
|
||||
}
|
||||
|
||||
while($myrow = pg_fetch_assoc($result)) {
|
||||
printf ("<tr><td>%s</td><td>%s</td><td>%d</td><td>%.1f</td><td>%d</td><td>%d</td><td>%d</td><td>%.1f</td><td>%.1f</td></tr>",
|
||||
$myrow['ai_ident_me'],$myrow['map'],$myrow['svn_release'],$myrow['win_percent'],$myrow['games'],$myrow['wins'],$myrow['losses'],$myrow['avg_win_turns'],$myrow['avg_loss_turns']);
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
<h2>By AI and own faction</h2>
|
||||
<table border=1>
|
||||
<tr>
|
||||
<th>AI</th>
|
||||
<th>Own faction</th>
|
||||
<th>SVN Release</th>
|
||||
<th>Win %</th>
|
||||
<th>Games</th>
|
||||
<th>Wins</th>
|
||||
<th>Losses</th>
|
||||
<th>Avg. turns to win</th>
|
||||
<th>Avg. turns to lose</th>
|
||||
</tr>
|
||||
<?php
|
||||
$query = "select ai_ident_me, faction_me, svn_release, avg_from(sum(win)*100,count(*)) as win_percent, count(*) as games, sum(win) as wins, sum(draw) as draws, sum(loss) as losses, avg_from(sum(win_turns),sum(win)) as avg_win_turns, avg_from(sum(loss_turns),sum(loss)) as avg_loss_turns from games_side group by ai_ident_me, faction_me, svn_release order by ai_ident_me, faction_me, svn_release desc;";
|
||||
$result = pg_query($query);
|
||||
if (!$result) {
|
||||
echo pg_last_error();
|
||||
exit();
|
||||
}
|
||||
|
||||
while($myrow = pg_fetch_assoc($result)) {
|
||||
printf ("<tr><td>%s</td><td>%s</td><td>%d</td><td>%.1f</td><td>%d</td><td>%d</td><td>%d</td><td>%.1f</td><td>%.1f</td></tr>",
|
||||
$myrow['ai_ident_me'],$myrow['faction_me'],$myrow['svn_release'],$myrow['win_percent'],$myrow['games'],$myrow['wins'],$myrow['losses'],$myrow['avg_win_turns'],$myrow['avg_loss_turns']);
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
<h2>By AI and enemy faction</h2>
|
||||
<table border=1>
|
||||
<tr>
|
||||
<th>AI</th>
|
||||
<th>Enemy faction</th>
|
||||
<th>SVN Release</th>
|
||||
<th>Win %</th>
|
||||
<th>Games</th>
|
||||
<th>Wins</th>
|
||||
<th>Losses</th>
|
||||
<th>Avg. turns to win</th>
|
||||
<th>Avg. turns to lose</th>
|
||||
</tr>
|
||||
<?php
|
||||
$query = "select ai_ident_me, faction_enemy, svn_release, avg_from(sum(win)*100,count(*)) as win_percent, count(*) as games, sum(win) as wins, sum(draw) as draws, sum(loss) as losses, avg_from(sum(win_turns),sum(win)) as avg_win_turns, avg_from(sum(loss_turns),sum(loss)) as avg_loss_turns from games_side group by ai_ident_me, faction_enemy, svn_release order by ai_ident_me, faction_enemy, svn_release desc;";
|
||||
$result = pg_query($query);
|
||||
if (!$result) {
|
||||
echo pg_last_error();
|
||||
exit();
|
||||
}
|
||||
|
||||
while($myrow = pg_fetch_assoc($result)) {
|
||||
printf ("<tr><td>%s</td><td>%s</td><td>%d</td><td>%.1f</td><td>%d</td><td>%d</td><td>%d</td><td>%.1f</td><td>%.1f</td></tr>",
|
||||
$myrow['ai_ident_me'],$myrow['faction_enemy'],$myrow['svn_release'],$myrow['win_percent'],$myrow['games'],$myrow['wins'],$myrow['losses'],$myrow['avg_win_turns'],$myrow['avg_loss_turns']);
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
<h2>By AI and factions</h2>
|
||||
<table border=1>
|
||||
<tr>
|
||||
<th>AI</th>
|
||||
<th>Own faction</th>
|
||||
<th>Enemy faction</th>
|
||||
<th>SVN Release</th>
|
||||
<th>Win %</th>
|
||||
<th>Games</th>
|
||||
<th>Wins</th>
|
||||
<th>Losses</th>
|
||||
<th>Avg. turns to win</th>
|
||||
<th>Avg. turns to lose</th>
|
||||
</tr>
|
||||
<?php
|
||||
$query = "select ai_ident_me, faction_me, faction_enemy, svn_release, avg_from(sum(win)*100,count(*)) as win_percent, count(*) as games, sum(win) as wins, sum(draw) as draws, sum(loss) as losses, avg_from(sum(win_turns),sum(win)) as avg_win_turns, avg_from(sum(loss_turns),sum(loss)) as avg_loss_turns from games_side group by ai_ident_me, faction_me, faction_enemy ,svn_release order by ai_ident_me, faction_me, faction_enemy, svn_release desc;";
|
||||
$result = pg_query($query);
|
||||
if (!$result) {
|
||||
echo pg_last_error();
|
||||
exit();
|
||||
}
|
||||
|
||||
while($myrow = pg_fetch_assoc($result)) {
|
||||
printf ("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%.1f</td><td>%d</td><td>%d</td><td>%d</td><td>%.1f</td><td>%.1f</td></tr>",
|
||||
$myrow['ai_ident_me'],$myrow['faction_me'],$myrow['faction_enemy'],$myrow['svn_release'],$myrow['win_percent'],$myrow['games'],$myrow['wins'],$myrow['losses'],$myrow['avg_win_turns'],$myrow['avg_loss_turns']);
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
|
||||
</body>
|
Loading…
Add table
Reference in a new issue