X-Git-Url: https://git.ucc.asn.au/?p=progcomp2012.git;a=blobdiff_plain;f=samples%2Fasmodeus%2Fasmodeus.py;fp=samples%2Fasmodeus%2Fasmodeus.py;h=29c50a29a2f707b31f323458cea0230c6d50f826;hp=2f83db66f1e41d2b572149a2efde73c5c739226e;hb=2120cc40abf9e3fd763c84a1e09b61064bb40be6;hpb=fe470c015d73d07c44f0e951a2bb205d95763f22 diff --git a/samples/asmodeus/asmodeus.py b/samples/asmodeus/asmodeus.py old mode 100755 new mode 100644 index 2f83db6..29c50a2 --- a/samples/asmodeus/asmodeus.py +++ b/samples/asmodeus/asmodeus.py @@ -14,201 +14,68 @@ git git.ucc.asn.au/progcomp2012.git ''' -import sys -import random - -ranks = ('B','1','2','3','4','5','6','7','8','9','s','F', '?', '+') - -def move(x, y, direction): - if direction == "UP": - return (x,y-1) - elif direction == "DOWN": - return (x,y+1) - elif direction == "LEFT": - return (x-1, y) - elif direction == "RIGHT": - return (x+1, y) - print "Error in move!" - return (x,y) - -def oppositeColour(colour): - if colour == "RED": - return "BLUE" - elif colour == "BLUE": - return "RED" - else: - return "NONE" - -class Piece: - def __init__(self, colour, rank, x, y): - self.colour = colour - self.rank = rank - self.x = x - self.y = y - - - - -class Asmodeus: - def __init__(self): - #sys.stderr.write("Asmodeus __init__ here...\n"); - self.turn = 0 - self.board = [] - self.units = [] - if self.Setup(): - while self.MoveCycle(): #derp derp derp - pass - +from basic_python import * +from path import * + - def Setup(self): - #sys.stderr.write("Asmodeus Setup here...\n"); - setup = sys.stdin.readline().split(' ') - self.colour = setup[0] - self.opponentName = setup[1] - self.width = int(setup[2]) - self.height = int(setup[3]) - for x in range(0, self.width): - self.board.append([]) - for y in range(0, self.height): - self.board[x].append(None) - if self.colour == "RED": - print "FB8sB479B8\nBB31555583\n6724898974\n967B669999" - elif self.colour == "BLUE": - print "967B669999\n6724898974\nBB31555583\nFB8sB479B8" - return True - - def MoveCycle(self): - #sys.stderr.write("Asmodeus MakeMove here...\n"); - if self.InterpretResult() == False or self.ReadBoard() == False or self.MakeMove() == False: - return False - self.turn += 1 - return self.InterpretResult() + +class Asmodeus(BasicAI): + " A slightly more advanced python based AI who calculates the optimum score for each move " + def __init__(self): + #sys.stderr.write("Asmodeus initialised...\n") + BasicAI.__init__(self) + self.riskScores = {'1' : 0.01 , '2' : 0.05 , '3' : 0.15 , '4' : 0.2, '5' : 0.2, '6' : 0.25, '7' : 0.25, '8' : 0.01 , '9' : 0.4, 's' : 0.01} + self.bombScores = {'1' : 0.0 , '2' : 0.0 , '3' : 0.05 , '4' : 0.1, '5' : 0.3, '6' : 0.4, '7' : 0.5, '8' : 1 , '9' : 0.6, 's' : 0.1} + self.flagScores = {'1' : 1.0 , '2' : 1.0 , '3' : 1.0 , '4' : 1.0, '5' : 1.0, '6' : 1.0, '7' : 1, '8' : 1.0 , '9' : 1.0, 's' : 1.0} + self.suicideScores = {'1' : 0.0 , '2' : 0.0 , '3' : 0.0, '4' : 0.0, '5' : 0.0, '6' : 0.05, '7' : 0.1, '8' : 0.0 , '9' : 0.0, 's' : 0.0} + self.killScores = {'1' : 1.0 , '2' : 0.9 , '3' : 0.8 , '4' : 0.5, '5' : 0.5, '6' : 0.5, '7' : 0.4, '8' : 0.9 , '9' : 0.6, 's' : 0.9} def MakeMove(self): - #TODO: Over-ride this function in base classes with more complex move behaviour - - #sys.stderr.write("Asmodeus MakeMove here...\n") - #self.debugPrintBoard() - while True: - if len(self.units) <= 0: - return False - piece = random.choice(self.units) - if piece == None: - continue - if piece.rank == '?' or piece.rank == 'B' or piece.rank == 'F': - continue + #sys.stderr.write("Asmodeus MakingMove...\n") + "Over-rides the default BasicAI.MakeMove function" - direction = random.choice(("UP", "DOWN", "LEFT", "RIGHT")) - p = move(piece.x, piece.y, direction) - if p[0] >= 0 and p[0] < self.width and p[1] >= 0 and p[1] < self.height: - if self.board[p[0]][p[1]] == None or self.board[p[0]][p[1]].colour == oppositeColour(self.colour): - print str(piece.x) + " " + str(piece.y) + " " + direction - break - return True - - - def ReadBoard(self): - #sys.stderr.write("Asmodeus ReadBoard here...\n"); - for y in range(0,self.height): - row = sys.stdin.readline() - for x in range(0,len(row)-1): - if self.turn == 0: - if row[x] == '.': - pass - elif row[x] == '#': - self.board[x][y] = Piece(oppositeColour(self.colour), '?',x,y) - elif row[x] == '+': - self.board[x][y] = Piece("NONE", '+', x, y) - else: - self.board[x][y] = Piece(self.colour, row[x],x,y) - self.units.append(self.board[x][y]) - else: - pass - return True - + moveList = [] + + for unit in self.units: + if unit.mobile() == False: + continue - def InterpretResult(self): - #sys.stderr.write("Asmodeus InterpretResult here...\n") - result = sys.stdin.readline().split(' ') - #sys.stderr.write(" Read status line \"" + str(result) + "\"\n") - if self.turn == 0: - return True + for enemy in self.enemyUnits: + if enemy == unit: + continue + path = PathFinder().pathFind((unit.x, unit.y), (enemy.x, enemy.y), self.board) - x = int(result[0].strip()) - y = int(result[1].strip()) + #sys.stderr.write("Computed path: " + str(path) + "\n") + if path == False or len(path) <= 0: + continue + score = self.CalculateScore(unit, enemy) + score = float(score / float(len(path) + 1)) + moveList.append([unit, path, enemy, score]) - #sys.stderr.write(" Board position " + str(x) + " " + str(y) + " is OK!\n") - direction = result[2].strip() - outcome = result[3].strip() - p = move(x,y,direction) - - if outcome == "OK": - self.board[p[0]][p[1]] = self.board[x][y] - self.board[x][y].x = p[0] - self.board[x][y].y = p[1] - - self.board[x][y] = None - elif outcome == "KILLS": - if self.board[p[0]][p[1]] == None: - return False - - if self.board[p[0]][p[1]].colour == self.colour: - self.units.remove(self.board[p[0]][p[1]]) - self.board[x][y].x = p[0] - self.board[x][y].y = p[1] - - - self.board[p[0]][p[1]] = self.board[x][y] - self.board[x][y].rank = result[4] - - self.board[x][y] = None - - elif outcome == "DIES": - if self.board[p[0]][p[1]] == None: - return False - - if self.board[x][y].colour == self.colour: - self.units.remove(self.board[x][y]) - - self.board[p[0]][p[1]].rank = result[5] - self.board[x][y] = None - elif outcome == "BOTHDIE": - if self.board[p[0]][p[1]] == None: - return False - - - if self.board[x][y].colour == self.colour: - self.units.remove(self.board[x][y]) - if self.board[p[0]][p[1]].colour == self.colour: - self.units.remove(self.board[p[0]][p[1]]) - self.board[p[0]][p[1]] = None - self.board[x][y] = None - elif outcome == "FLAG": - #sys.stderr.write(" Game over!\n") - return False - elif outcome == "ILLEGAL": - #sys.stderr.write(" Illegal move!\n") - return False + if len(moveList) <= 0: + #sys.stderr.write("NO Moves!\n") + return BasicAI.MakeMove(self) + + moveList.sort(key = lambda e : e[len(e)-1], reverse=True) + + #sys.stderr.write("Chosen move is: " + str(moveList[0][0].x) + " " + str(moveList[0][0].y) + " " + moveList[0][1][0] + " (targeting enemy with rank " + moveList[0][2].rank + " at position " + str(moveList[0][2].x) + " " + str(moveList[0][2].y) + " (my rank " + moveList[0][0].rank+")\n") + print str(moveList[0][0].x) + " " + str(moveList[0][0].y) + " " + moveList[0][1][0] + return True + + def CalculateScore(self, attacker, defender): + if defender.rank == '?': + return self.riskScores[attacker.rank] + elif defender.rank == 'B': + return self.bombScores[attacker.rank] + elif defender.rank == 'F': + return self.flagScores[attacker.rank] + elif defender.valuedRank() < attacker.valuedRank() or defender.rank == '1' and attacker.rank == 's': + return self.killScores[defender.rank] else: - #sys.stderr.write(" Don't understand outcome \"" + outcome + "\"!\n"); - return False - - #sys.stderr.write(" Completed interpreting move!\n"); - return True - - def debugPrintBoard(self): - for y in range(0, self.height): - for x in range(0, self.width): - if self.board[x][y] == None: - sys.stderr.write("."); - else: - sys.stderr.write(str(self.board[x][y].rank)); - sys.stderr.write("\n") - - - -asmodeus = Asmodeus() + return self.suicideScores[attacker.rank] + +