Chess Counter (python source)
From SnOwy - Ed's Wiki Notebook
ChessCounter.py (draft)
#TODO: Fix bug that prevents this from working on rectangular boards
#TODO: Add turret support for Omega Chess
#TODO: Add safe check analysis
#TODO: Fix bug that prevents this from working on 8*8 boards ???
import math # for euler's number
ranks = 10 #integers only
files = 10 #integers only
EMP = '`' # ... an empty square has this value
OCC = '#' # ... an occupied square has this value
#ME = 'O'
def Show(list2D):
for r in list2D:
printStr = ""
for f in r:
printStr += f
print printStr
def ShowAll(pDict):
for k in pDict:
print "== " + k + " =="
Show(pDict[k])
def Compose(a, b):
retList = []
for ra, rb in zip(a, b):
retInner = []
for fa, fb in zip(ra, rb):
if fa == OCC or fb == OCC:
retInner.append(OCC)
else:
retInner.append(EMP)
retList.append(retInner)
return retList
def Centre(template):
r = ranks *2 +1
f = files *2 +1
shiftR = r/2 - (len(template)+1)/2
shiftF = f/2 - (len(template)+1)/2 # |--->[ ]----|
pushR = r/2 + (len(template)+1)/2
pushF = f/2 + (len(template)+1)/2 # |----[ ]<---|
retList = []
for i in xrange(r):
retInner = []
for j in xrange(f):
if i > shiftR and j > shiftF and i < pushR and j < pushF:
retInner.append(template[i-shiftR-1][j-shiftF-1])
else:
retInner.append(EMP)
retList.append(retInner)
return retList
def Rook():
r = ranks *2 +1
f = files *2 +1
retList = []
for i in xrange(r):
retInner = []
for j in xrange(f):
if i == r/2 and j == f/2:
retInner.append(EMP)
elif i == r/2 or j == f/2:
retInner.append(OCC)
else:
retInner.append(EMP)
retList.append(retInner)
return retList
def Gryphon():
r = ranks *2 +1
f = files *2 +1
retList = []
for i in xrange(r):
retInner = []
for j in xrange(f):
if i == r/2 or j == f/2:
retInner.append(EMP)
elif i == r/2+1 or i == r/2-1 or j == f/2+1 or j == f/2-1:
retInner.append(OCC)
else:
retInner.append(EMP)
retList.append(retInner)
return retList
def Bishop():
r = ranks *2 +1
f = files *2 +1
retList = []
for i in xrange(r):
retInner = []
for j in xrange(f):
if i == r/2 and j == f/2:
retInner.append(EMP)
elif i == j or r-i == j+1:
retInner.append(OCC)
else:
retInner.append(EMP)
retList.append(retInner)
return Centre(retList)
def Aanca():
r = ranks *2 +1
f = files *2 +1
retList = []
for i in xrange(r):
retInner = []
for j in xrange(f):
if i == j-1 or i == j+1 or r-i == j or r-i == j+2:
retInner.append(OCC)
else:
retInner.append(EMP)
retList.append(retInner)
return Centre(retList)
def Nightrider():
r = ranks *2 +1
f = files *2 +1
retList = []
for i in xrange(r):
retInner = []
for j in xrange(f):
if i == r/2 and j == f/2:
retInner.append(EMP)
elif i == 0.5*j+(files/2) or i == 2*j-(files) or i == f -0.5*j-(files/2+1) or i == f -2*j+(files-1):
retInner.append(OCC)
else:
retInner.append(EMP)
retList.append(retInner)
return Centre(retList)
def Leaper(pattern):
d = max([max(tup) for tup in pattern]) *2 +1
pSet = set()
for p in pattern:
pSet.add((d/2 + p[0], d/2 + p[1]))
pSet.add((d/2 + p[0], d/2 + -1*p[1]))
pSet.add((d/2 + p[1], d/2 + p[0]))
pSet.add((d/2 + p[1], d/2 + -1*p[0]))
pSet.add((d/2 + -1*p[0], d/2 + p[1]))
pSet.add((d/2 + -1*p[0], d/2 + -1*p[1]))
pSet.add((d/2 + -1*p[1], d/2 + p[0]))
pSet.add((d/2 + -1*p[1], d/2 + -1*p[0]))
retList = []
for i in xrange(d):
retList.append([EMP for j in xrange(d)])
for p in pSet:
retList[p[0]][p[1]] = OCC
return Centre(retList)
pieces = {}
pieces["King (FIDE)"] = Leaper([(0,1),(1,1)])
pieces["Rook (FIDE)"] = Rook()
pieces["Bishop (FIDE)"] = Bishop()
pieces["Queen (FIDE)"] = Compose(pieces["Rook (FIDE)"], pieces["Bishop (FIDE)"])
pieces["Knight (FIDE)"] = Leaper([(1,2)])
pieces["Champion (Omega)"] = Leaper([(0,1),(0,2),(2,2)])
pieces["Wizard (Omega)"] = Leaper([(1,1),(1,3)])
pieces["Elephant (Seirawan)"] = Compose(pieces["Knight (FIDE)"], pieces["Rook (FIDE)"])
pieces["Hawk (Seirawan)"] = Compose(pieces["Knight (FIDE)"], pieces["Bishop (FIDE)"])
#pieces["* Knight +(0,1; 0,3)"] = Leaper([(0,1),(0,3),(1,2)])
#pieces["* Knight +(0,1; 0,3; 2,3)"] = Leaper([(0,1),(0,3),(1,2),(2,3)])
#pieces["* Knight +(0,3; 2,3)"] = Leaper([(0,3),(1,2),(2,3)])
#pieces["* Knight +(0,1; 2,3)"] = Leaper([(0,1),(1,2),(2,3)])
#pieces["* Knight +(2,3)"] = Leaper([(1,2),(2,3)])
#pieces["* Knight +(0,1)"] = Leaper([(0,1),(1,2)])
#pieces["* Knight +(0,3)"] = Leaper([(0,3),(1,2)])
#pieces["* Gryphon"] = Gryphon()
#pieces["* Aanca"] = Aanca()
#pieces["* Camel (1,3)"] = Leaper([(1,3)])
#pieces["* Ferz (1,1) - bound 0.5"] = Leaper([(1,1)])
#pieces["* Dabbabah (0,2) - bound 0.25"] = Leaper([(0,2)])
#pieces["* (0,1)"] = Leaper([(0,1)])
#pieces["* Alfil (2,2) - bound 0.125"] = Leaper([(2,2)])
#pieces["* Nightrider"] = Nightrider()
#ShowAll(pieces)
def ReportControl(list2D):
retDict = {}
for i in xrange(ranks):
for j in xrange(files):
#print i, j
thisBoard = list2D[i+1:i+ranks+1]
newBoard = []
for line in thisBoard:
newLine = line[j+1:j+ranks+1]
newBoard.append(newLine)
#Show(newBoard)
ocount = 0
for row in newBoard:
for square in row:
if square == OCC:
ocount += 1
oratio = float(ocount) / float(ranks * files)
try:
retDict[oratio]
except:
retDict[oratio] = 1
else:
retDict[oratio] += 1
return retDict
bottom = 0.0
top = 0.0
motilityDict = {}
for p in pieces:
cDict = ReportControl(pieces[p])
#print p
motility = 0.0
for cd in sorted(cDict):
#print "\t", cd, cDict[cd]
motility += cd * cDict[cd]
#print ">>>\t", motility
motilityDict[motility] = p
if p == "Knight (FIDE)":
bottom = motility
elif p == "Queen (FIDE)":
top = motility
def Logistic(low, high, value):
t = (value-low) / (high-low) * 8.0 - 4.0
return 3 + (1.0 / (1 + math.e ** -t)) * 7
#print "linear\tsigmoid\tpiece"
for m in reversed(sorted(motilityDict)):
#print str((m-bottom)/(top-bottom)*7+3)[0:4] + " \t" + str(Logistic(bottom, top, m))[0:4] + " \t" + motilityDict[m]
print m, motilityDict[m]
#ReportSafeCheck(pieces["rook"])