Changeset - 3798475f45c1
[Not reviewed]
default
6 5 7
Laman - 7 years ago 2017-12-05 00:27:22

refactoring: moving files around
12 files changed with 20 insertions and 21 deletions:
0 comments (0 inline, 0 general)
src/analyzer/__init__.py
Show inline comments
 
file renamed from src/imageanalyzer.py to src/analyzer/__init__.py
 
import logging as log
 
from grid import Grid
 
from go import exportBoard
 
import go
 
from .grid import Grid
 
from go.core import exportBoard, EMPTY,BLACK,WHITE
 

	
 

	
 
class ImageAnalyzer:
 

	
 
	def __init__(self,tresB=30,tresW=60):
 
		self.board=[[go.EMPTY]*19 for r in range(19)]
 
		self.board=[[EMPTY] * 19 for r in range(19)]
 
		self.grid=None
 

	
 
		self.tresB=tresB
 
		self.tresW=tresW
 

	
 
	# let's not concern ourselves with sizecoef and shift here anymore. we want corners to come already properly recomputed
 
	def analyze(self,image):
 
		if self.grid==None:
 
			log.info("ImageAnalyzer.analyze() aborted: no grid available.")
 
			return False
 

	
 
		for r in range(19):
 
@@ -39,27 +38,27 @@ class ImageAnalyzer:
 
					red,green,blue=image.getpixel((x,y))
 
				except IndexError: continue
 

	
 
				I=(red+green+blue)/255/3
 
				m=min(red,green,blue)
 
				S=1-m/I if I!=0 else 0
 
				if 100*I<self.tresB: b+=1
 
				elif 100*I>self.tresW: w+=1
 
				else: e+=1
 

	
 
		log.debug("(%d,%d) ... (b=%d,w=%d,e=%d)", row, col, b, w, e)
 

	
 
		if b>=w and b>=e: return go.BLACK
 
		if w>=b and w>=e: return go.WHITE
 
		return go.EMPTY
 
		if b>=w and b>=e: return BLACK
 
		if w>=b and w>=e: return WHITE
 
		return EMPTY
 

	
 
	def setGridCorners(self,corners):
 
		self.grid=Grid(corners)
 

	
 

	
 
def relevantRect(imageCoords,stoneWidth,stoneHeight):
 
	x=int(imageCoords.x)
 
	y=int(imageCoords.y)
 
	xmax=max(int(stoneWidth*2//7), 2) # !! optimal parameters subject to further research
 
	ymax=max(int(stoneHeight*2//7), 2)
 

	
 
	return ((x-xmax,y-ymax), (x+xmax,y+ymax))
src/analyzer/corners.py
Show inline comments
 
file renamed from src/corners.py to src/analyzer/corners.py
 
from epoint import EPoint
 
from .epoint import EPoint
 

	
 

	
 
class Corners:
 
	def __init__(self):
 
		self.corners=[]
 

	
 
	## Adds a new corner if there are less than four, replaces the closest otherwise.
 
	def add(self,x,y):
 
		a=EPoint(x,y)
 
		# for i,c in enumerate(self.corners): # move an improperly placed point
 
			# if a.dist(c)<20:
 
				# self.corners[i]=a
src/analyzer/epoint.py
Show inline comments
 
file renamed from src/epoint.py to src/analyzer/epoint.py
src/analyzer/grid.py
Show inline comments
 
file renamed from src/grid.py to src/analyzer/grid.py
 
import numpy
 
from epoint import EPoint
 
from .epoint import EPoint
 

	
 

	
 
## Projective transformation of a point with a matrix A.
 
#  
 
#  Takes a point as a horizontal vector, transposes it and multiplies with A from left.
 
#  
 
#  @return transformed point as a numpy.array
 
def transformPoint(point,A):
 
	return (A*numpy.matrix(point).transpose()).getA1()
 

	
 

	
 
class Grid:
src/core.py
Show inline comments
 
import os
 
import multiprocessing
 
import threading
 
import logging as log
 
import PIL
 
from util import MsgQueue
 
from gui import gui
 
from imageanalyzer import ImageAnalyzer
 
from go import Go, isLegalPosition
 
from analyzer import ImageAnalyzer
 
from go.core import Go, isLegalPosition
 
from statebag import StateBag
 
import config as cfg
 

	
 

	
 
class Core:
 
	def __init__(self):
 
		self.grid=None
 
		self.go=Go()
 
		self.detector=ImageAnalyzer()
 
		self.states=StateBag()
 

	
 
		self._ownMessages=MsgQueue(self._handleEvent)
src/go/__init__.py
Show inline comments
 
new file 100644
src/go/core.py
Show inline comments
 
file renamed from src/go.py to src/go/core.py
 
import logging as log
 

	
 
from util import EMPTY,BLACK,WHITE,colorNames
 
from gamerecord import GameRecord
 
from .gamerecord import GameRecord
 

	
 

	
 
class Go:
 
	## Initializes self.board to a list[r][c]=EMPTY.
 
	def __init__(self,boardSize=19):
 
		self.boardSize=boardSize
 
		self.board=[[EMPTY]*boardSize for x in range(boardSize)]
 
		self._temp=[[EMPTY]*boardSize for x in range(boardSize)]
 
		self.toMove=BLACK
 
		self._record=GameRecord()
 

	
 
	## Executes a move.
src/go/gamerecord.py
Show inline comments
 
file renamed from src/gamerecord.py to src/go/gamerecord.py
src/gui/boardview.py
Show inline comments
 
from .resizablecanvas import ResizableCanvas
 
from go import BLACK,WHITE
 
from go.core import BLACK,WHITE
 

	
 

	
 
## Handles and presents the game state as detected by the program.
 
class BoardView(ResizableCanvas):
 
	def __init__(self, master=None):
 
		super().__init__(master)
 

	
 
		self.configure(width=360,height=360,background="#ffcc00")
 

	
 
		self._padding=18
 
		self._cellWidth=(self._width-2*self._padding)/18
 
		self._cellHeight=(self._height-2*self._padding)/18
src/gui/imgview.py
Show inline comments
 
import logging as log
 

	
 
from PIL import ImageTk
 

	
 
import config
 
from .resizablecanvas import ResizableCanvas
 
from corners import Corners
 
from epoint import EPoint
 
from grid import Grid
 
import imageanalyzer
 
from analyzer.corners import Corners
 
from analyzer.epoint import EPoint
 
from analyzer.grid import Grid
 
import analyzer
 

	
 

	
 
class ImgView(ResizableCanvas):
 
	def __init__(self,master=None,parent=None):
 
		super().__init__(master)
 

	
 
		self._parent=parent
 
		self._corners=Corners()
 
		self._boardGrid=None
 

	
 
		self._img=None
 
		self._tkImg=None
 
@@ -41,25 +41,25 @@ class ImgView(ResizableCanvas):
 
			for r in range(19):
 
				a=self._boardGrid.intersections[r][0]
 
				b=self._boardGrid.intersections[r][-1]
 
				self.create_line(a.x,a.y,b.x,b.y,fill='#00ff00')
 
			for c in range(19):
 
				a=self._boardGrid.intersections[0][c]
 
				b=self._boardGrid.intersections[-1][c]
 
				self.create_line(a.x,a.y,b.x,b.y,fill='#00ff00')
 

	
 
		if self._boardGrid!=None and config.gui.showBigPoints:
 
			for r in range(19):
 
				for c in range(19):
 
					((r1,c1),(r2,c2))=imageanalyzer.relevantRect(self._boardGrid.intersections[r][c], *(self._boardGrid.stoneSizeAt(r, c)))
 
					((r1,c1),(r2,c2))=analyzer.relevantRect(self._boardGrid.intersections[r][c], *(self._boardGrid.stoneSizeAt(r, c)))
 
					self.create_rectangle(r1,c1,r2,c2,outline="#00ffff")
 

	
 
	def setImg(self,img):
 
		self._img=img
 

	
 
	## Stores a grid corner located at x,y coordinates.
 
	def addCorner(self,x,y):
 
		self._corners.add(x,y)
 
		log.debug("click on %d,%d",x,y)
 
		if self._corners.canonizeOrder():
 
			# transform corners from show coordinates to real coordinates
 
			log.debug(self._corners.corners)
src/statebag.py
Show inline comments
 
@@ -8,26 +8,26 @@ It is relatively cheap to add new items 
 
User can change detector parameters, presumably in case the previous don't fit the (current) situation.
 
In such a case we assume the new parameters are correct from the current position onwards.
 
But the change might have been appropriate even earlier (before the user detected and fixed an error).
 
So we try to find the correct crossover point like this:
 
- construct a sequence S' = s'_i, ..., s'_n by reanalyzing the positions with a new set of parameters, where s_i is the point of previous user intervention or s_0
 
- for each s'_j:
 
	- try to append it to S[:j]
 
	- try to append it to S'[:j]
 
	- remember the better variant
 
- linearize the fork back by discarding s'_j-s preceding the crossover and s_j-s following the crossover
 
"""
 

	
 
from util import BLACK,WHITE,EMPTY
 
from go import transitionSequence
 
from util import EMPTY
 
from go.core import transitionSequence
 

	
 

	
 
## Crude lower bound on edit distance between states.
 
def estimateDistance(diff):
 
	additions=sum(1 for d in diff if d[2]=="+")
 
	deletions=sum(1 for d in diff if d[2]=="-")
 
	replacements=len(diff)-additions-deletions
 
	if additions>0: return additions+replacements
 
	elif replacements==0 and deletions>0: return 2 # take n, return 1
 
	return replacements # ???
 

	
 

	
src/tests/testGo.py
Show inline comments
 
from unittest import TestCase
 

	
 
from go import isLegalPosition
 
from go.core import isLegalPosition
 

	
 

	
 
class TestLegal(TestCase):
 
	def testLegal(self):
 
		board=[
 
			[0,0,0,0,0],
 
			[1,1,1,1,1],
 
			[-1,-1,0,1,0],
 
			[0,0,0,-1,-1],
 
			[0,-1,0,-1,0]
 
		]
 
		self.assertTrue(isLegalPosition(board))
0 comments (0 inline, 0 general)