Warning
This page is located in archive. Go to the latest version of this course pages. Go the latest version of this page.

import base as Base
import copy, random, time, math
from PIL import Image, ImageDraw
 
 
# Player template for HIVE --- ALP semestral work
# Vojta Vonasek, 2023
 
 
# PUT ALL YOUR IMPLEMENTATION INTO THIS FILE
 
class Spider:
    def __init__(self, p,q, parent=None):
        self.p = p
        self.q = q
        self.path=[]
        self.parent = None  #not important
 
 
 
class Player(Base.Board):
    def __init__(self, playerName, myIsUpper, size, myPieces, rivalPieces):  #do not change this line
        Base.Board.__init__(self, myIsUpper, size, myPieces, rivalPieces)    #do not change this line
        self.playerName = playerName
        self.algorithmName = "myGreatMethod"
 
 
    def getAllEmptyCells(self):
        result = []
        for p in self.board:
            for q in self.board[p]:
                if self.isEmpty(p,q, self.board):
                    result.append( [p,q] )                        
        return result
 
 
    def getAllNonemptyCells(self):                    
        result = []
        for p in self.board:
            for q in self.board[p]:
                if not self.isEmpty(p,q, self.board):
                    result.append( [p,q] )                        
        return result
 
 
    def move(self):
        """ return [animal, oldP, oldQ, newP, newQ], or [animal, None, None, newP, newQ] or [] """
 
        #the following code just randomly places (ignoring all the rules) some random figure at the board
        emptyCells = self.getAllEmptyCells()
 
        if len(emptyCells) == 0:
            return []
 
        randomCell = emptyCells[ random.randint(0, len(emptyCells)-1) ]
        randomP, randomQ = randomCell
 
        for animal in self.myPieces:
            if self.myPieces[animal] > 0: #is this animal still available? if so, let's place it
                return [ animal, None, None, randomP, randomQ ]
 
 
 
        #all animals are places, let's move some randomly (again, while ignoring all rules)
        allFigures = self.getAllNonemptyCells()
        randomCell = allFigures[ random.randint(0, len(allFigures)-1) ]
        randomFigureP, randomFigureQ = randomCell
        #determine which animal is at randomFigureP, randomFigureQ
        animal = self.board[ randomFigureP ][ randomFigureQ ][-1]   # [-1] means the last letter
        return [animal, randomFigureP, randomFigureQ, randomP, randomQ ]
 
    def canSlide(self, p,q, lp, lq, board):
 
        SN = {}
        SN[ (1,0) ] = [ [1,-1], [0,1] ]
        SN[ (1,-1) ] = [ [0,-1], [1,0] ]
        SN[ (0,-1) ] = [ [1,-1], [-1,0] ]
        SN[ (-1,0) ] = [ [0,-1], [-1,1] ]
        SN[ (-1,1) ] = [ [-1,0], [0,1] ]
        SN[ (0,1) ] = [ [-1,1], [1,0 ] ]
 
        newp, newq = p+lp, q+lq
        if self.inBoard(newp, newq) and \
           self.isEmpty(newp, newq, board):
            for cell in SN[ (lp, lq ) ]:
                cellp, cellq = cell
                cellp += p
                cellq += q
                if self.inBoard(cellp, cellq) and \
                   self.isEmpty(cellp, cellq, board):
                    return True
        return False
 
    def spiderMoves(self, p,q): 
        #return list of all paths
        result = []
 
        start = Spider(p,q)
        start.path = [ [p,q] ]
        queue = [ start ]
        N = [ [1,-1],[0,-1],[-1,0],[-1,1], [0,1] ,[1,0]]
        while len(queue) > 0:
            act = queue.pop()
            #if goal
            if len(act.path) == 4:
                result.append(act.path)
                continue
 
            #expanze
            for cell in N:
                cellp, cellq = cell
                if self.canSlide(act.p, act.q, cellp, cellq, self.board):
                    newp, newq = act.p + cellp, act.q + cellq
                    newState = Spider( newp, newq )
                    newState.path = copy.deepcopy(act.path) + [ [newp, newq] ]
                    queue.insert(0, newState )
 
        result2 = []
        for path in result:
            isWrong = False
            for i in range(len(path) - 1):
                p1,q1 = path[i]
                p2,q2 = path[i+1]
                if self.shareNeighbors(p1,q1,p2,q2):
                    pass
                else:
                    isWrong = True
                    break
            if isWrong == False:
                result2.append( path)
        return result2
 
 
    def listNonemptyNeighbors(self, p,q):
        N = [ [1,-1],[0,-1],[-1,0],[-1,1], [0,1] ,[1,0]]
        nec = {}
        for cell in N:
            cellp, cellq = cell
            cellp += p
            cellq += q
            if self.inBoard(cellp, cellq) and not self.isEmpty(cellp, cellq, self.board):
                nec[ (cellp, cellq) ] = True
        return nec
 
 
    def shareNeighbors(self, p1,q1, p2,q2):
        NEC1 = self.listNonemptyNeighbors(p1,q1)
        NEC2 = self.listNonemptyNeighbors(p2,q2)
        for cell in NEC1:
            if cell in NEC2:
                return True
 
        return False
 
 
    def testSpider(self):
        self.board[6][6] = "S"
        self.board[6][7] = "a"
        self.board[5][7] = "a"
        moves = self.spiderMoves(6,6)
        moveidx = 0
        for path in moves:
            #path = [ [p,q], ... [p,q] ]
 
            HL = {}
            for cell in path:
                HL[ (cell[0], cell[1]) ] = "#00FF00"
            self.saveImage("spider"+str(moveidx) + ".png", HL=HL)
            moveidx += 1
 
 
 
 
 
 
 
 
 
 
    def test(self):
        N = [ [1,-1],[0,-1],[-1,0],[-1,1], [0,1] ,[1,0]]
        self.board[6][6] = "S"
        self.board[7][5] = "a"
        self.board[6][7] = "a"
        p,q = 6,6  #### TEST POZICE
        frame = 0
        for cell in N:
            lp, lq = cell
            if self.canSlide(p,q, lp, lq, self.board):
                newp, newq = p + lp, q+ lq
                #self.board[newp][newq] = "Q"
                HL = {}
                HL[ (newp, newq) ] = "#00FF00"
                self.saveImage("move"+str(frame) + ".png", HL=HL)
                frame += 1
 
 
 
def updatePlayers(move, activePlayer, passivePlayer):
    """ write move made by activePlayer player
        this method assumes that all moves are correct, no checking is made
    """
    if len(move) == 0:
        return
 
    animal, p,q, newp, newq = move
    if p == None and q == None:
        #placing new animal
        activePlayer.myPieces[animal]-=1
        passivePlayer.rivalPieces = activePlayer.myPieces.copy()
    else:
        #just moving animal
        #delete its old position
        activePlayer.board[p][q] = activePlayer.board[p][q][:-1]
        passivePlayer.board[p][q] = passivePlayer.board[p][q][:-1]
 
    activePlayer.board[newp][newq] += animal
    passivePlayer.board[newp][newq] += animal
 
 
 
 
if __name__ == "__main__":
    boardSize = 13
    smallFigures = { "q":1, "a":2, "b":2, "s":2, "g":2 }  #key is animal, value is how many is available for placing
    bigFigures = { figure.upper(): smallFigures[figure] for figure in smallFigures } #same, but with upper case
 
    P1 = Player("player1", False, 13, smallFigures, bigFigures)
    P2 = Player("player2", True, 13, bigFigures, smallFigures)
 
    filename = "begin.png"
    P1.saveImage(filename)
 
    P1.testSpider()
    print("end")
 
 
    moveIdx = 0
    while True:
        break
 
        move = P1.move()
        print("P1 returned", move)
        updatePlayers(move, P1, P2)  #update P1 and P2 according to the move
        filename = "move-{:03d}-player1.png".format(moveIdx) 
        P1.saveImage(filename)     
 
 
        move = P2.move()
        print("P2 returned", move)
        updatePlayers(move, P2, P1) #update P2 and P1 according to the move
        filename = "move-{:03d}-player2.png".format(moveIdx)
        P1.saveImage(filename)
 
        moveIdx += 1
        P1.myMove = moveIdx
        P2.myMove = moveIdx
 
        if moveIdx > 50:
            print("End of the test game")
            break

courses/b3b33alp/cviceni/faq/spiderdraft2.txt · Last modified: 2023/12/18 17:43 by vonasvoj