def testDrawPoint(self): sq = Square(-1, 5) self.assertRaises(TypeError, self.b.getSquare, 4) self.assertRaises(BoardException, self.b.getSquare, sq) sq = Square(3, 2) self.b.drawPoint(sq, 3) self.assertEqual(3, self.b.getSquare(Square(3, 2)))
def testHit(self): sq = Square(3, 2) self.b.drawPoint(sq, 8) self.b.hit(sq) self.assertEqual(1, self.b.getSquare(sq)) sq = Square(5, 2) self.b.hit(sq) self.assertEqual(0, self.b.getSquare(sq))
def testHit(self): self.pl.drawPlane(Plane(Square(0, 2))) self.pl.drawPlane(Plane(Square(7, 4), orientation="down")) self.assertEqual(2, len(self.pl._planes)) x = self.pl.hit(Square(0, 2)) self.assertEqual(len(x), 10) x = self.pl.hit(Square(5, 4)) self.assertEqual(len(x), 1) x = self.pl.hit(Square(0, 0)) self.assertEqual(len(x), 1)
def onClick(self, idx): if self.playerMove and not self._game.board.isWon( ) and self._game.board.getValAtPos(Square(idx // 15, idx % 15)) == 0: self.pushButtons[idx].setStyleSheet( "background-color: rgb(0, 0, 0);") self._game.moveHuman(Square(idx // 15, idx % 15), 'X') if self._game.board.isWon(): self.gameWon() return self.playerMove = False self.computerMove()
def testDrawing(self): self.pl.drawPlane(Plane(Square(0, 2))) self.assertEqual(1, len(self.pl._planes)) self.pl.cleanPlanes() self.assertEqual(0, len(self.pl._planes)) self.pl.drawPlane(Plane(Square(0, 2))) self.pl.drawPlane(Plane(Square(7, 4), orientation="down")) self.assertEqual(2, len(self.pl._planes)) self.assertEqual(2, self.pl.alivePlanes) self.assertEqual(2, len(self.ai._planes))
def left(self): self.__clearCoords() self._planeCoords[0].append(self.cabinPos) for i in range(-(self.upperWings // 2), self.upperWings // 2 + 1): self._planeCoords[1].append(Square(i, 1) + self.cabinPos) for i in range(2, self.body - 1): self._planeCoords[2].append(Square(0, i) + self.cabinPos) lp = self.lowerWings // 2 for i in range(-lp, lp + 1): self._planeCoords[3].append( Square(i, self.body - 1) + self.cabinPos) return self._planeCoords
def _addSqToQ(self, q, sq): ''' Adds valid squares around given one into list q Input: - q - list of squares - sq - Square ''' for i in [-1, 1]: sq1 = Square(sq.longitude + i, sq.latitude) sq2 = Square(sq.longitude, sq.latitude + i) if 0 <= sq1.latitude <= 7 and self.getSquareStatus(sq1) != 0 and self.getSquareStatus(sq1) != 1: q.append(Square(sq.longitude + i, sq.latitude)) if 0 <= sq2.latitude <= 7 and self.getSquareStatus(sq1) != 0 and self.getSquareStatus(sq1) != 1: q.append(Square(sq.longitude, sq.latitude + i))
def down(self): self.__clearCoords() self._planeCoords[0].append(self.cabinPos) for i in range(-(self.upperWings // 2), self.upperWings // 2 + 1): self._planeCoords[1].append( Square(self.cabinPos.longitude - 1, i + self.cabinPos.latitude)) for i in range(self.body - 3, 0, -1): self._planeCoords[2].append( Square(self.cabinPos.longitude - i - 1, self.cabinPos.latitude)) lp = self.lowerWings // 2 for i in range(-lp, lp + 1): self._planeCoords[3].append( Square(self.cabinPos.longitude - self.body + 1, i + self.cabinPos.latitude)) return self._planeCoords
def saveState(self, fileName): #try: sqList = [] for i in range(8): for j in range(8): if self._board.board[i][j] == 'x': sqList.append(Square(i, j)) writeFile(fileName, sqList)
def do_tests(self): x = Square() y = x.getElem(1, 1) self.assertEqual(y, '0', "FATAL ERROR") x = Square() y = x.getElem(0, 0) self.assertEqual(y, '0', "FATAL ERROR") y = x.getElem(5, 5) self.assertEqual(y, '0', "FATAL ERROR") contr = Controller(x) contr.block(0, 0) y = x.getElem(2, 2) self.assertEqual(y, '0', "FATAL ERROR") y = x.getElem(0, 0) self.assertEqual(y, 'X', "FATAL ERROR")
def testUpdate(): x = Game() patt = x.loadPattern('block') x.placePattern(patt, Square(0, 0)) x.update() sm = 0 for i in range(8): for j in range(8): if x.board.board[i][j] == 'x': sm += 1 assert sm == 4
def testPlace(): x = Game() patt = x.loadPattern('block') x.placePattern(patt, Square(0, 0)) sm = 0 for i in range(8): for j in range(8): if x.board.board[i][j] == 'x': sm += 1 assert sm == 4 x.placePattern(patt, Square(3, 3)) sm = 0 for i in range(8): for j in range(8): if x.board.board[i][j] == 'x': sm += 1 assert sm == 8 try: x.placePattern(patt, Square(0, 0)) assert False except Exception: assert True
def moveComputerMinimax(self, computerTurn, computerSymbol, playerSymbol, depth): ''' computerTurn - bool computerSymbol, playerSymbol - 'O'(2) and 'X'(1) depth - int ''' color = '' bestScore = 0 if computerTurn: color = computerSymbol bestScore = 1000000000 else: color = playerSymbol bestScore = -1000000000 bestMove = Square(-1, -1) analysis = 0 moves = self._getMoves() goodMoves = [] for i in range(len(moves) - 1, -1, -1): self._board.move(moves[i], color) if depth == 1: analysis = self._analyzeGomoku(computerTurn, color) else: if self._board.isWon(): return [bestMove, bestScore] response = self.moveComputerMinimax(not computerTurn, computerSymbol, playerSymbol, depth - 1) analysis = response[1] self._board.move(moves[i], ' ') if (analysis < bestScore and computerTurn) or (analysis > bestScore and not computerTurn): bestScore = analysis bestMove = moves[i] goodMoves.append(moves[i]) elif analysis == bestScore: goodMoves.append(moves[i]) theBestScore = -1000000000 for move in goodMoves: self._board.move(moves[i], color) analysis = self._analyzeGomoku(computerTurn, color) if analysis > theBestScore: bestMove = move self._board.move(moves[i], ' ') return [bestMove, bestScore]
def _analyzeHorizontal(self, computerTurn, symbolNr): ''' computerTurn - bool symbolNr - 1 or 2 ''' score = 0 countConsecutive = 0 openEnds = 0 for i in range(15): for j in range(15): # Board has 15x15 squares if (self._board.getValAtPos(Square(i, j)) == symbolNr): countConsecutive += 1 elif (self._board.getValAtPos(Square(i, j)) == 0 and countConsecutive > 0): openEnds += 1 score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 1 elif (self._board.getValAtPos(Square(i, j)) == 0): openEnds = 1 elif (countConsecutive > 0): score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 0 else: openEnds = 0 if (countConsecutive > 0): score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 0 return score
def update(self, nTimes=1): ''' Updates the tables status of nTimes by default being 1 using given rules input: nTimes - integer ''' newSt = Board() while nTimes > 0: nTimes -= 1 for i in range(8): for j in range(8): nei = self.getNbOfNei(Square(i, j)) if nei == 2 or nei == 3: newSt.board[i][j] = 'x' if self._board.board[i][j] == '0' and nei == 3: newSt.board.board[i][j] = 'x' self._board = deepcopy(newSt)
def inputPosToSquare(self, strg): moves = "123456789ABCDEFGHabcdefgh" if len(strg) != 2: raise ValueError("Inccorect command!") if strg[0] not in moves or strg[1] not in moves: raise ValueError( "Inccorect coords! They must be between 1-8 and A-H") if strg[0].isnumeric() and strg[1].isalpha(): x = self.strgToVal(strg[0]) y = self.strgToVal(strg[1]) elif strg[1].isnumeric() and strg[0].isalpha(): y = self.strgToVal(strg[0]) x = self.strgToVal(strg[1]) else: raise ValueError("Inccorect command!") return Square(x, y)
def _getMoves(self): moves = [] for option in self._board.getSquaresWithVal( 0): # Get squares near 'X' or 'O' for k in range(9): i = k // 3 - 1 j = k % 3 - 1 if option.row + i not in range( 0, 15) or option.col + j not in range(0, 15): continue if self._board.getValAtPos( Square(option.row + i, option.col + j)) != 0: moves.append(option) break return moves
def play(self): if self._status: crtIndex = self.aiBoard.currentIndex() sq = Square(crtIndex.row() - 1, crtIndex.column() - 1) if sq.latitude + 1 > 0 and sq.longitude + 1 > 0: try: stat = self._game.aiB.getSquareStatus(sq) sq = self._game.aiB.hit(sq) self.hitOnBoard(sq, stat, self.aiBoard) if not self.checkGameOver(): #sq, stat = self._game.playerB.aiHit() sq, stat = self._game.playerB.aiHitSmarter() self.hitOnBoard(sq, stat, self.playerBoard) self.checkGameOver() except Exception as err: self.createDialog(str(err), "Incorect hit!", QtWidgets.QMessageBox.Information)
def checkPos(self, strg): moves = "12345678ABCDEFGHabcdefgh" cmds = strg.split() if len(cmds) != 2: raise ValueError( "Position must be of form: 3A UP(up|down|righ|left)!") if strg[0] not in moves or strg[1] not in moves: raise ValueError( "Inccorect coords! They must be between 1-8 and A-H") if strg[0].isnumeric() and strg[1].isalpha(): x = self.strgToVal(strg[0]) y = self.strgToVal(strg[1]) elif strg[1].isnumeric() and strg[0].isalpha(): y = self.strgToVal(strg[0]) x = self.strgToVal(strg[1]) else: raise ValueError("Inccorect command!") return Square(x, y)
def genPlanes(board): ''' Generates valid plane's for a given board Input: - plane - Plane - board - Board Output: - planesL - List of valid Planes ''' planesL = [] for i in range(board.height): for j in range(board.lenght): for ori in ["up", "down", "left", "right"]: try: pl = Plane(Square(i, j), orientation=ori) board.validatePlaneCoords(pl) planesL.append(pl) except Exception: pass return planesL
def __init__(self, board, nbPlanes=2, player=0, *planes): ''' Player=(0,1) 0-computer; 1-human; ''' self._board = board self._planes = [] if player == 1: if len(planes): self._planes = planes for plane in self._planes: self.drawPlane(plane) elif player == 0: self._setComputerPlanes(nbPlanes) self._aiHittingPos = [] for i in range(self._board.height): for j in range(self._board.lenght): self._aiHittingPos.append(Square(i, j)) self._aiSmarterMoves = [] self._aiMovesNb = self._board.lenght * self._board.height self._alivePlanes = nbPlanes
def __init__(self, cabinPos=Square(0, 0), orientation="up", upperWings=5, lowerWings=3, body=4): ''' Initialize a plane with: cabin - Square which represents planes cabin position orientation - string between ["up", "down", "left", "right"] which are planes orientation uperWings - int lenght of upper planes wings (5 by default) lowerWings - int lenght of lower planes wings (3 by default) body - int lenght of body (4 by default) ''' self._cabin = cabinPos self._orientation = orientation.lower() self._uw = upperWings self._lw = lowerWings self._bd = body PlaneValidator(self).validate() self._planeCoords = [[] for x in range(self.body)] self.__setOrientation()
def printBoard(self, btype='player'): ''' Returns a textable with the current board using boardType(btype) to know if planes should be displayed or not Input: - btaype - string, by default is 'player' and displays the planes if it's not player it will not display the planes Output: - table - string which contains the board to be print ''' boardToPrint = deepcopy(self._board).board table = Texttable() let = [''] for i in range(self._board.lenght): let.append(ascii_uppercase[i]) table.add_row(let) for i in range(self._board.height): for j in range(self._board.lenght): if boardToPrint[i][j] == 0: boardToPrint[i][j] = "O" elif boardToPrint[i][j] == 1: boardToPrint[i][j] = "X" elif boardToPrint[i][j] == 8 and btype == "player": boardToPrint[i][j] = "*" elif boardToPrint[i][j] == 9 and btype == "player": x = self.__findPlane(Square(i, j)) if x.orientation == "up": boardToPrint[i][j] = "^" elif x.orientation == "down": boardToPrint[i][j] = "v" elif x.orientation == "left": boardToPrint[i][j] = "<" elif x.orientation == "right": boardToPrint[i][j] = ">" else: boardToPrint[i][j] = " " boardToPrint[i].insert(0, str(i + 1)) table.add_row(boardToPrint[i]) return table.draw()
def setUp(self): self.p = Plane(cabinPos=Square(0, 2))
def testCr(self): lis = [ Square(0, 2), Square(1, 0), Square(1, 1), Square(1, 2), Square(1, 3), Square(1, 4), Square(1, 5), Square(2, 2), Square(3, 1), Square(3, 2), Square(3, 3) ] liInd = 0 for body in self.p.getCoords: for sq in body: if sq == lis[liInd]: liInd += 1 else: self.assertFalse()
def _analyzeSecondaryDiagonal(self, computerTurn, symbolNr): ''' computerTurn - bool symbolNr - 1 or 2 ''' score = 0 countConsecutive = 0 openEnds = 0 # Above and on diagonal for a in range(4, 15): # Go only where it's possible to get 5 i = 0 j = a for b in range(a): # Board has 15x15 squares if (self._board.getValAtPos(Square(i, j)) == symbolNr): countConsecutive += 1 elif (self._board.getValAtPos(Square(i, j)) == 0 and countConsecutive > 0): openEnds += 1 score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 1 elif (self._board.getValAtPos(Square(i, j)) == 0): openEnds = 1 elif (countConsecutive > 0): score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 0 else: openEnds = 0 i += 1 j -= 1 if (countConsecutive > 0): score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 0 # Below the diagonal for a in range(1, 11): # Go only where it's possible to get 5 i = a j = 14 for b in range(15 - a): # Board has 15x15 squares if (self._board.getValAtPos(Square(i, j)) == symbolNr): countConsecutive += 1 elif (self._board.getValAtPos(Square(i, j)) == 0 and countConsecutive > 0): openEnds += 1 score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 1 elif (self._board.getValAtPos(Square(i, j)) == 0): openEnds = 1 elif (countConsecutive > 0): score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 0 else: openEnds = 0 i += 1 j -= 1 if (countConsecutive > 0): score += self._gomokuShapeScore(countConsecutive, openEnds, computerTurn) countConsecutive = 0 openEnds = 0 return score
def testValidPlane(self): self.assertTrue( self.b.validatePlaneCoords(Plane(cabinPos=Square(0, 2)))) self.b.hit(Square(2, 2)) self.assertFalse( self.b.validatePlaneCoords(Plane(cabinPos=Square(2, 2))))
def testGetSq(self): sq = Square(-1, 5) self.assertRaises(TypeError, self.b.getSquare, 4) self.assertRaises(BoardException, self.b.getSquare, sq) self.b.board[3][2] = 1 self.assertEqual(self.b.board[3][2], self.b.getSquare(Square(3, 2)))
from domain.square import Square from controller.squareController import Controller from ui.ui import ui from tests import MyTestCase sqr = Square() Test = MyTestCase() Test.do_tests() a = Controller(sqr) cons = ui(a, "data/Pattern.txt", "data/configuration.txt") cons.run()
def place(cmd): pat = game.loadPattern(cmd[0]) game.placePattern(pat, Square(int(cmd[1][0]), int(cmd[1][2])))