Chess Counter (python source)

From SnOwy - Ed's Wiki Notebook

Jump to: navigation, search

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"])
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox