from direct.distributed.DistributedNodeAI import DistributedNodeAI from direct.distributed.ClockDelta import * from direct.fsm import ClassicFSM, State from direct.fsm import State from direct.fsm import StateData from direct.distributed.ClockDelta import * from toontown.safezone import CheckersBoard class DistributedCheckersAI(DistributedNodeAI): def __init__(self, air, parent, name, x, y, z, h, p, r): DistributedNodeAI.__init__(self, air) self.name = name self.air = air self.setPos(x, y, z) self.setHpr(h, p, r) self.myPos = (x, y, z) self.myHpr = (h, p, r) self.board = CheckersBoard.CheckersBoard() self.parent = self.air.doId2do[parent] self.parentDo = parent self.wantStart = [] self.playersPlaying = [] self.playersSitting = 0 self.playersTurn = 1 self.movesMade = 0 self.playerNum = 1 self.hasWon = False self.playersGamePos = [ None, None] self.wantTimer = True self.timerEnd = 0 self.turnEnd = 0 self.playersObserving = [] self.winLaffPoints = 20 self.movesRequiredToWin = 10 self.zoneId = self.air.allocateZone() self.generateOtpObject(air.districtId, self.zoneId, optionalFields = [ 'setX', 'setY', 'setZ', 'setH', 'setP', 'setR']) self.parent.setCheckersZoneId(self.zoneId) self.startingPositions = [ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]] self.kingPositions = [ [ 31, 30, 29, 28], [ 0, 1, 2, 3]] self.timerStart = None self.fsm = ClassicFSM.ClassicFSM('Checkers', [ State.State('waitingToBegin', self.enterWaitingToBegin, self.exitWaitingToBegin, [ 'playing']), State.State('playing', self.enterPlaying, self.exitPlaying, [ 'gameOver']), State.State('gameOver', self.enterGameOver, self.exitGameOver, [ 'waitingToBegin'])], 'waitingToBegin', 'waitingToBegin') self.fsm.enterInitialState() def announceGenerate(self): self.parent.setGameDoId(self.doId) def getTableDoId(self): return self.parentDo def delete(self): self.fsm.requestFinalState() self.board.delete() del self.fsm DistributedNodeAI.delete(self) def informGameOfPlayer(self): self.playersSitting += 1 if self.playersSitting < 2: self.timerEnd = 0 else: if self.playersSitting == 2: self.timerEnd = globalClock.getRealTime() + 20 self.parent.isAccepting = False self.parent.sendUpdate('setIsPlaying', [ 1]) else: if self.playersSitting > 2: pass self.sendUpdate('setTimer', [ globalClockDelta.localToNetworkTime(self.timerEnd)]) def informGameOfPlayerLeave(self): self.playersSitting -= 1 if self.playersSitting < 2 and self.fsm.getCurrentState().getName() == 'waitingToBegin': self.timerEnd = 0 self.parent.isAccepting = True self.parent.sendUpdate('setIsPlaying', [ 0]) if self.playersSitting > 2 and self.fsm.getCurrentState().getName() == 'waitingToBegin': pass else: self.timerEnd = 0 if self.timerEnd != 0: self.sendUpdate('setTimer', [ globalClockDelta.localToNetworkTime(self.timerEnd)]) else: self.sendUpdate('setTimer', [ 0]) def setGameCountdownTime(self): self.timerEnd = globalClock.getRealTime() + 10 def setTurnCountdownTime(self): self.turnEnd = globalClock.getRealTime() + 40 def getTimer(self): if self.timerEnd != 0: return 0 else: return 0 def getTurnTimer(self): return globalClockDelta.localToNetworkTime(self.turnEnd) def requestTimer(self): avId = self.air.getAvatarIdFromSender() self.sendUpdateToAvatarId(avId, 'setTimer', [ globalClockDelta.localToNetworkTime(self.timerEnd)]) def handlePlayerExit(self, avId): if avId in self.wantStart: self.wantStart.remove(avId) if self.fsm.getCurrentState().getName() == 'playing': gamePos = self.playersGamePos.index(avId) self.playersGamePos[gamePos] = None self.fsm.request('gameOver') def handleEmptyGame(self): self.movesMade = 0 self.playersTurn = 1 self.playerNum = 1 self.fsm.request('waitingToBegin') self.parent.isAccepting = True def requestWin(self): avId = self.air.getAvatarIdFromSender() def distributeLaffPoints(self): for x in self.parent.seats: if x != None: av = self.air.doId2do.get(x) av.toonUp(self.winLaffPoints) def enterWaitingToBegin(self): self.setGameCountdownTime() self.parent.isAccepting = True def exitWaitingToBegin(self): self.turnEnd = 0 def enterPlaying(self): self.parent.isAccepting = False for x in self.playersGamePos: if x != None: self.playersTurn = self.playersGamePos.index(x) self.d_sendTurn(self.playersTurn + 1) break self.setTurnCountdownTime() self.sendUpdate('setTurnTimer', [ globalClockDelta.localToNetworkTime(self.turnEnd)]) def exitPlaying(self): pass def enterGameOver(self): self.timerEnd = 0 isAccepting = True self.parent.handleGameOver() self.playersObserving = [] self.playersTurn = 1 self.playerNum = 1 self.clearBoard() self.sendGameState([]) self.movesMade = 0 self.playersGamePos = [ None, None, None, None, None, None] self.parent.isAccepting = True self.fsm.request('waitingToBegin') def exitGameOver(self): pass def requestBegin(self): avId = self.air.getAvatarIdFromSender() if avId not in self.wantStart: self.wantStart.append(avId) numPlayers = 0 for x in self.parent.seats: if x != None: numPlayers = numPlayers + 1 if len(self.wantStart) == numPlayers and numPlayers >= 2: self.d_gameStart(avId) self.parent.sendIsPlaying() def d_gameStart(self, avId): for x in self.playersObserving: self.sendUpdateToAvatarId(x, 'gameStart', [ 255]) zz = 0 numPlayers = 0 for x in self.parent.seats: if x != None: numPlayers += 1 self.playersPlaying.append(x) if numPlayers == 2: player1 = self.playersPlaying[0] self.sendUpdateToAvatarId(player1, 'gameStart', [ 1]) self.playersGamePos[0] = player1 for x in self.startingPositions[0]: self.board.setState(x, 1) player2 = self.playersPlaying[1] self.sendUpdateToAvatarId(player2, 'gameStart', [ 2]) self.playersGamePos[1] = player2 for x in self.startingPositions[1]: self.board.setState(x, 2) self.sendGameState([]) self.wantStart = [] self.fsm.request('playing') self.parent.getTableState() def d_sendTurn(self, playersTurn): self.sendUpdate('sendTurn', [ playersTurn]) def advancePlayerTurn(self): if self.playersTurn == 0: self.playersTurn = 1 self.playerNum = 2 else: self.playerNum = 1 self.playersTurn = 0 def requestMove(self, moveList): if self.checkLegalMoves(moveList) == True: self.makeMove(moveList) self.advancePlayerTurn() self.d_sendTurn(self.playersTurn + 1) self.setTurnCountdownTime() self.sendUpdate('setTurnTimer', [ globalClockDelta.localToNetworkTime(self.turnEnd)]) else: avId = self.air.getAvatarIdFromSender() self.sendUpdateToAvatarId(avId, 'illegalMove', []) self.air.writeServerEvent('suspicious', avId, 'has requested an illegal move in Regular checkers - not possible') def checkLegalMoves(self, moveList): if self.board.squareList[moveList[0]].getState() >= 3: moveType = 'king' else: moveType = 'normal' if len(moveList) == 2: firstSquare = self.board.squareList[moveList[0]] secondSquare = self.board.squareList[moveList[1]] if self.checkLegalMove(firstSquare, secondSquare, moveType) == True: return True else: for x in xrange(len(moveList) - 1): y = self.checkLegalJump(self.board.getSquare(moveList[x]), self.board.getSquare(moveList[x + 1]), moveType) if y == False: return False else: return True return False elif len(moveList) > 2: for x in xrange(len(moveList) - 1): y = self.checkLegalJump(self.board.getSquare(moveList[x]), self.board.getSquare(moveList[x + 1]), moveType) if y == False: return False return True def makeMove(self, moveList): for x in xrange(len(moveList) - 1): firstSquare = self.board.squareList[moveList[x]] secondSquare = self.board.squareList[moveList[x + 1]] if firstSquare.getNum() in secondSquare.getAdjacent(): break index = firstSquare.jumps.index(secondSquare.getNum()) self.board.squareList[firstSquare.getAdjacent()[index]].setState(0) haveMoved = False squareState = self.board.squareList[moveList[0]].getState() if squareState <= 2: piecetype = 'normal' if squareState == 1: playerNum = 1 else: playerNum = 2 else: piecetype = 'king' if squareState == 3: playerNum = 1 else: playerNum = 2 if piecetype == 'normal': lastElement = moveList[len(moveList) - 1] if playerNum == 1: if lastElement in self.kingPositions[0]: self.board.squareList[moveList[0]].setState(0) self.board.squareList[lastElement].setState(3) haveMoved = True self.sendGameState(moveList) elif lastElement in self.kingPositions[1]: self.board.squareList[moveList[0]].setState(0) self.board.squareList[lastElement].setState(4) haveMoved = True self.sendGameState(moveList) if haveMoved == False: spot1 = self.board.squareList[moveList[0]].getState() self.board.squareList[moveList[0]].setState(0) self.board.squareList[moveList[len(moveList) - 1]].setState(spot1) self.sendGameState(moveList) temp = self.playerNum self.playerNum = 1 if self.hasWon == True: return if self.hasPeicesAndMoves(1, 3) == False: self.parent.announceWinner('Checkers', self.playersPlaying[1]) self.fsm.request('gameOver') self.hasWon = True return self.playerNum = temp temp = self.playerNum self.playerNum = 2 if self.hasPeicesAndMoves(2, 4) == False: self.parent.announceWinner('Checkers', self.playersPlaying[0]) self.fsm.request('gameOver') self.hasWon = True return self.playerNum = temp def hasPeicesAndMoves(self, normalNum, kingNum): for x in self.board.squareList: if x.getState() == normalNum: if self.existsLegalMovesFrom(x.getNum(), 'normal') == True: return True if self.existsLegalJumpsFrom(x.getNum(), 'normal') == True: return True else: if x.getState() == kingNum: if self.existsLegalMovesFrom(x.getNum(), 'king') == True: return True if self.existsLegalJumpsFrom(x.getNum(), 'king') == True: return True return False def getState(self): return self.fsm.getCurrentState().getName() def getName(self): return self.name def getGameState(self): return [ self.board.getStates(), []] def sendGameState(self, moveList): gameState = self.board.getStates() self.sendUpdate('setGameState', [ gameState, moveList]) def clearBoard(self): for x in self.board.squareList: x.setState(0) def getPosHpr(self): return self.posHpr def existsLegalJumpsFrom(self, index, peice): if peice == 'king': for x in xrange(4): if self.board.squareList[index].getAdjacent()[x] != None and self.board.squareList[index].getJumps()[x] != None: adj = self.board.squareList[self.board.squareList[index].getAdjacent()[x]] jump = self.board.squareList[self.board.squareList[index].getJumps()[x]] if adj.getState() == 0: pass elif adj.getState() == self.playerNum or adj.getState() == self.playerNum + 2: pass elif jump.getState() == 0: return True return False elif peice == 'normal': if self.playerNum == 1: moveForward = [ 1, 2] elif self.playerNum == 2: moveForward = [ 0, 3] for x in moveForward: if self.board.squareList[index].getAdjacent()[x] != None and self.board.squareList[index].getJumps()[x] != None: adj = self.board.squareList[self.board.squareList[index].getAdjacent()[x]] jump = self.board.squareList[self.board.squareList[index].getJumps()[x]] if adj.getState() == 0: pass elif adj.getState() == self.playerNum or adj.getState() == self.playerNum + 2: pass elif jump.getState() == 0: return True return False def existsLegalMovesFrom(self, index, peice): if peice == 'king': for x in self.board.squareList[index].getAdjacent(): if x != None: if self.board.squareList[x].getState() == 0: return True return False elif peice == 'normal': if self.playerNum == 1: moveForward = [ 1, 2] elif self.playerNum == 2: moveForward = [ 0, 3] for x in moveForward: if self.board.squareList[index].getAdjacent()[x] != None: adj = self.board.squareList[self.board.squareList[index].getAdjacent()[x]] if adj.getState() == 0: return True return False def existsLegalJumpsFrom(self, index, peice): if peice == 'king': for x in xrange(4): if self.board.squareList[index].getAdjacent()[x] != None and self.board.squareList[index].getJumps()[x] != None: adj = self.board.squareList[self.board.squareList[index].getAdjacent()[x]] jump = self.board.squareList[self.board.squareList[index].getJumps()[x]] if adj.getState() == 0: pass elif adj.getState() == self.playerNum or adj.getState() == self.playerNum + 2: pass elif jump.getState() == 0: return True return False elif peice == 'normal': if self.playerNum == 1: moveForward = [ 1, 2] elif self.playerNum == 2: moveForward = [ 0, 3] for x in moveForward: if self.board.squareList[index].getAdjacent()[x] != None and self.board.squareList[index].getJumps()[x] != None: adj = self.board.squareList[self.board.squareList[index].getAdjacent()[x]] jump = self.board.squareList[self.board.squareList[index].getJumps()[x]] if adj.getState() == 0: pass elif adj.getState() == self.playerNum or adj.getState() == self.playerNum + 2: pass elif jump.getState() == 0: return True return False def checkLegalMove(self, firstSquare, secondSquare, peice): if self.playerNum == 1: moveForward = [ 1, 2] else: moveForward = [ 0, 3] if peice == 'king': for x in xrange(4): if firstSquare.getAdjacent()[x] != None: if self.board.squareList[firstSquare.getAdjacent()[x]].getState() == 0: return True return False elif peice == 'normal': for x in moveForward: if firstSquare.getAdjacent()[x] != None: if self.board.squareList[firstSquare.getAdjacent()[x]].getState() == 0: return True return False def checkLegalJump(self, firstSquare, secondSquare, peice): if self.playerNum == 1: moveForward = [ 1, 2] opposingPeices = [ 2, 4] else: moveForward = [ 0, 3] opposingPeices = [ 1, 3] if peice == 'king': if secondSquare.getNum() in firstSquare.getJumps(): index = firstSquare.getJumps().index(secondSquare.getNum()) if self.board.squareList[firstSquare.getAdjacent()[index]].getState() in opposingPeices: return True else: return False elif peice == 'normal': if secondSquare.getNum() in firstSquare.getJumps(): index = firstSquare.getJumps().index(secondSquare.getNum()) if index in moveForward: if self.board.squareList[firstSquare.getAdjacent()[index]].getState() in opposingPeices: return True else: return False else: return False else: return False