Author: esr
Date: Tue Apr 24 13:26:52 2007
New Revision: 17028
URL: http://svn.gna.org/viewcvs/wesnoth?rev=17028&view=rev
Log:
The new Python version of map_convert, and the regression-test harness to
verify that
it behaves like the Perl script. After a bit more polishing this is going to
go away,
with the Python code getting folded into upconvert.
Added:
trunk/data/tools/map_convert.py (with props)
trunk/data/tools/regress (with props)
Added: trunk/data/tools/map_convert.py
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/data/tools/map_convert.py?rev=17028&view=auto
==============================================================================
--- trunk/data/tools/map_convert.py (added)
+++ trunk/data/tools/map_convert.py Tue Apr 24 13:26:52 2007
@@ -1,0 +1,231 @@
+#!/usr/bin/env python
+# Script to convert from single char 1.2.x-style maps to multiple character
+# 1.3.1-style maps. This is a straight translation of the Perl created for
+# regression-testing against the Perl version; the final version of the
+# conversion logic will be folded into upconvert.
+
+import sys, os, re
+
+def printUsage():
+ print "map_convert.pl terrain.cfg map_file.cfg [new_map_file.cfg]\n"
+
+def get_adjacent(x, y, map):
+ "Returns string of original location+adjacent locations on hex 1-char map"
+ odd = (x) % 2
+ adj = map[y][x];
+ if x > 0:
+ adj += map[y][x-1]
+ if x < len(map[y])-1:
+ adj += map[y][x+1]
+ if y > 0:
+ adj += map[y-1][x]
+ if y < len(map)-1:
+ adj += map[y+1][x]
+ if x > 0 and y > 0 and not odd:
+ adj += map[y-1][x-1]
+ if x < len(map[y])-1 and y > 0 and not odd:
+ adj += map[y-1][x+1];
+ if x > 0 and y < len(map)-1 and odd:
+ adj += map[y+1][x-1]
+ if x < len(map[y])-1 and y < len(map)-1 and odd:
+ adj += map[y+1][x+1]
+ adj = adj.replace("\n", "").replace("\r", "")
+ return adj
+
+if len(sys.argv) < 3 or len(sys.argv) > 4:
+ printUsage()
+ sys.exit(1)
+
+sys.argv.pop(0)
+terrain_file = sys.argv.pop(0)
+map_file = sys.argv.pop(0)
+if not sys.argv:
+ new_map_file = map_file;
+ backup = map_file + ".bak";
+ try:
+ os.system("cp %s %s" % (map_file, backup))
+ except:
+ sys.stderr.write("map_convert: could not create backup file: %s\n" %
backup)
+ sys.exit(1)
+else:
+ new_map_file = sys.argv.pop(0)
+ if os.path.exists(new_map_file):
+ sys.stderr.write("map_convert: new map file already exists: %s\n"
%new_map_file)
+ sys.exit(1)
+
+if not os.path.exists(terrain_file):
+ sys.stderr.write("map_convert: can not read terrain file:
%s\n"%terrain_file)
+ sys.exit(1)
+
+if not os.path.exists(map_file):
+ sys.stderr.write("can not read map file: %s\n" % map_file)
+ sys.exit(1)
+
+conversion = {}
+conversion["1"] = '1 _K'
+conversion["2"] = '2 _K'
+conversion["3"] = '3 _K'
+conversion["4"] = '4 _K'
+conversion["5"] = '5 _K'
+conversion["6"] = '6 _K'
+conversion["7"] = '7 _K'
+conversion["8"] = '8 _K'
+conversion["9"] = '9 _K'
+conversion[" "] = '_s'
+
+# Parse terrain_file
+tfp = open(terrain_file)
+countdef = 0
+max_len = 0
+while True:
+ line = tfp.readline()
+ if not line:
+ break
+
+ # Skip ifdef'd comments
+ if line.startswith("#ifdef"):
+ countdef +=1;
+ if line.startswith("#endif"):
+ countdef -=1;
+ elif not line.startswith("#") and countdef == 0:
+ # Parse [terrain] blocks
+ if "[terrain]" in line:
+ char = ''
+ string = ''
+ inside = True
+ while inside:
+ line = tfp.readline()
+ if not line:
+ break
+ line = line.strip().replace(" ", "").replace("\t", "")
+ if line.startswith("char"):
+ char = line[4:]
+ (dummy, char) = char.split('=');
+ char = char.replace('"', '')
+ if char:
+ char = char[0]
+ elif line.startswith("string"):
+ string=line[6:]
+ (dummy, string) = string.split('=')
+ string = string.replace('"', '')
+ elif line.startswith("[/terrain]"):
+ inside = False
+ if char and len(char) == 1 and string:
+ if len(string) > max_len:
+ max_len = len(string)
+ conversion[char] = string;
+tfp.close()
+width = max_len+2
+#keys = conversion.keys()
+#keys.sort()
+#for k in keys:
+# print "%s -> %s" % (k, conversion[k])
+
+# This hairy regexp excludes map_data lines that contain {} file references,
+# also lines that are empty or hold just one keep character (somewhat
+# pathological, but not handling these will make the regression tests break).
+mapdata = re.compile(r'map_data="[A-Za-z0-9\/|\\&_~?\[\]\']{2,}')
+
+mfile = []
+map_only = not map_file.endswith(".cfg")
+for line in open(map_file):
+ mfile.append(line);
+ if mapdata.search(line):
+ map_only = False
+#mfile.append("\n")
+
+cont = False
+outmap = []
+newfile = []
+lineno = baseline = 0
+while mfile:
+ line = mfile.pop(0)
+ lineno += 1
+ if map_only or mapdata.search(line):
+ baseline = 0
+ cont = True
+ # Assumes map is more than 1 line long.
+ if not map_only:
+ line = line.split('"')[1]
+ if line:
+ outmap.append(line)
+ while cont and mfile:
+ line = mfile.pop(0)
+ lineno += 1
+ if line and line[0] == '#':
+ newfile.append(line)
+ continue
+ if '"' in line:
+ cont = False
+ line = line.split('"')[0]
+ if line and not line.endswith("\n"):
+ line += "\n"
+ if line:
+ outmap.append(line)
+ if not map_only:
+ line="map_data=\"\n";
+ newfile.append(line)
+ y = 0
+ for oldline in outmap:
+ x = 0
+ if "," in oldline:
+ sys.stderr.write("mapconvert map file %s appears "
+ "to be converted already\n" % map_file)
+ sys.exit(1)
+ line = ''
+ for char in oldline:
+ ohex = ''
+ format = "%%%d.%ds" % (width, max_len)
+ if char in ('\n', '\r'):
+ ohex += char
+ elif char in conversion:
+ ohex = format % conversion[char] + ','
+ else:
+ sys.stderr.write('map_convert: "%s", line %d: unrecognized
character %s (%d) at (%d, %d)\n' % \
+ (map_file, baseline+y+1, `char`,
ord(char), x, y))
+ # ohex = format % char
+ sys.exit(1)
+ if "_K" in ohex:
+ # Convert keeps according to adjacent hexes
+ adj = get_adjacent(x,y, outmap)
+ # print "adjacent: adj\n";
+ hexcount = {}
+ for i in range(1, len(adj)):
+ # Intentionally skipping 0 as it is original hex
+ a = adj[i];
+ if not a in conversion:
+ sys.stderr.write('map_convert: "%s", line %d:
error in adjacent hexes at (%d, %d).\n' % \
+ (map_file, baseline+y+1, x, y))
+ sys.exit(1)
+ ca = conversion[a]
+ if ca.startswith("C"): #this is a castle hex
+ hexcount[ca] = hexcount.get(ca, 0) + 1
+ maxc = 0;
+ maxk = "Ch";
+ for k in hexcount:
+ if hexcount[k] > maxc:
+ maxc = hexcount[k]
+ maxk = k
+ maxk = re.sub("^C", "K", maxk)
+ ohex = ohex.replace("_K", maxk)
+ line += ohex
+ x += 1
+ # We've accumulated a translated map line
+ newfile.append(line.replace(",\n", "\n"))
+ y += 1
+ # All lines of the map are processed, add the appropriate trailer
+ if map_only:
+ line="\n"
+ else:
+ line="\"\n"
+ newfile.append(line)
+ else:
+ newfile.append(line)
+
+ofp = open(new_map_file, "w");
+ofp.writelines(newfile)
+ofp.close()
+
+# map_convert ends here.
+
+
Propchange: trunk/data/tools/map_convert.py
------------------------------------------------------------------------------
svn:executable = *
Added: trunk/data/tools/regress
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/data/tools/regress?rev=17028&view=auto
==============================================================================
--- trunk/data/tools/regress (added)
+++ trunk/data/tools/regress Tue Apr 24 13:26:52 2007
@@ -1,0 +1,39 @@
+#!/bin/bash
+#
+# Test map_convert.py against map_convert.pl.
+# If these scripts are really equivalent, we should see no diffs.
+
+# UMC should point at a mirror of the campaign server
+UMC=../../umc
+TERRAIN=../terrain.cfg
+
+cleanup() {
+ find $UMC -type f -regex '.*-p[ly]' -exec rm {} \;
+}
+
+cleanup;
+
+# The enumeration relies on $ not being in any filename
+for file in `find $UMC -name '*.cfg' | tr ' ' '$'; find $UMC -type f
-wholename '*/maps/*'`
+do
+ file=`echo $file | tr '$' ' '`
+ echo "${file}"
+ if map_convert.pl ${TERRAIN} "${file}" "${file}-pl"
+ then
+ if map_convert.py ${TERRAIN} "${file}" "${file}-py"
+ then
+ diff -u "${file}-pl" "${file}-py"
+ else
+ echo "Python conversion failed"
+ exit 1
+ fi
+ else
+ echo "Perl conversion failed"
+ continue
+ #exit 1
+ fi
+done
+
+# -pl and -py files are left in place only if something failed
+cleanup;
+exit 0
Propchange: trunk/data/tools/regress
------------------------------------------------------------------------------
svn:executable = *
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits