def startGame(): '''Start the game.''' print "The computer makes the first step" ai = Ai() started = True ai.play() print "The board now looks like this:" printBoard(convert(status))
class Game: def __init__(self,tablero,jugador1,jugador2,con_jugadas_posibles=True,nivel=Ai.FACIL, write_path=""): #self.__gui = Gui() #self.__tablero = self.__gui.init_board().get_board() self.__tablero_g = tablero self.__tablero = tablero.get_logical_board() #Iniciliazo la inteligencia para la PC self.__pc = Ai(nivel) #Inicializo un vector de jugadores self.__jugadores = [jugador1,jugador2] self.__ganador = "" self.__nro_turno = 0 self.__termino_juego = False self.__juego_mesh = False self.__con_jugadas_posibles = con_jugadas_posibles self.__lista_jugadas_posibles = [] if write_path != "": #Imprimo en el log la configuracion del juego que se inicia try: f = open(os.path.abspath(write_path + "/data/game.log"),'r') f.close() self.__log_file = open(os.path.abspath(write_path + "/data/game.log"),'a') print >> self.__log_file, '\nGAME LOG: ' + time.asctime() except: self.__log_file = open(os.path.abspath(write_path + "/data/game.log"),'w') print >> self.__log_file, 'GAME LOG: ' + time.asctime() print >> self.__log_file, 'Tablero: ' + str(self.__tablero.get_dimension()) + 'x' + str(self.__tablero.get_dimension()) if jugador1.get_color() == board.BLANCO and jugador1.get_name() == PC: print >> self.__log_file, 'PC: Blanco' print >> self.__log_file, 'Jugador: Negro' elif jugador1.get_name() == HUMANO and jugador2.get_name() == HUMANO: if jugador1.get_color() == board.BLANCO: print >> self.__log_file, 'Jugador1: Blanco' print >> self.__log_file, 'Jugador2: Negro' else: print >> self.__log_file, 'Jugador1: Negro' print >> self.__log_file, 'Jugador2: Blanco' else: print >> self.__log_file, 'PC: Negro' print >> self.__log_file, 'Jugador: Blanco' def __del__(self): try: self.__log_file.close() except: log.debug("Problemas al cerrar el descriptor de archivo. (Game Class)") def get_game_log_file(self): return self.__log_file def get_turn(self): return self.__jugadores[self.__turno] def set_turn(self,jugador): if jugador.equal(self.__jugadores[0]): self.__turno = 0 elif jugador.equal(self.__jugadores[1]): self.__turno = 1 else: raise Exception("No se pudo asignar el turno, el jugador no existe! (Game Class)") self.update_possible_moves() def update_possible_moves(self): self.__lista_jugadas_posibles = Referee.possibles_moves(self.get_turn().get_color(),self.__tablero) def increase_turn_number(self): self.__nro_turno += 1 def get_turn_number(self): return self.__nro_turno def __next_turn(self): color = self.__jugadores[self.__turno].get_color() #Veo si hay jugada posible para el turno siguiente, es decir si era Blanco para el Negro if Referee.is_at_least_one_move(color*-1, self.__tablero): return True else: return False def with_possibles_moves(self): return self.__con_jugadas_posibles def change_turn(self): #if self.__next_turn(): self.__turno = (self.__turno - 1) * -1 self.increase_turn_number() # return True #else: # return False def is_over(self): if Referee.is_at_least_one_move(board.BLANCO, self.__tablero): return False elif Referee.is_at_least_one_move(board.NEGRO, self.__tablero): return False else: return True def init_next_turn(self): pass def __print_log(self, mensaje): try: print >> self.__log_file, mensaje except: print mensaje def get_mesh_game(self): return self.__juego_mesh def set_mesh_game(self, valor): self.__juego_mesh = valor def play(self, coord="", audio="", marcador="", ventana="", extra=""): pc_manual = False if not self.is_over(): jugadas_posibles_real = len(self.__lista_jugadas_posibles) self.__ultima_jugada_humano = "" if jugadas_posibles_real > 0: nombre_de_turno = self.get_turn().get_name() color_de_turno = self.get_turn().get_color() if nombre_de_turno == HUMANO or nombre_de_turno == VIRTUAL: if coord == "": coord = self.__tablero_g.get_coord_selected_cell() if color_de_turno == board.BLANCO: pudo_jugar = self.__tablero_g.set_piece(coord,color_de_turno,"blanco",audio, ventana) sonido_voltear = "voltear_negro" else: pudo_jugar = self.__tablero_g.set_piece(coord,color_de_turno,"negro",audio, ventana) sonido_voltear = "voltear_blanco" if pudo_jugar: marcador.render_numbers(self.__tablero,self.get_turn().get_color(),ventana) self.__ultima_jugada_humano = coord self.__print_log("JUGADOR jugo en: " + str(self.__ultima_jugada_humano)) if nombre_de_turno == VIRTUAL: self.__tablero_g.set_coord_selected_cell(coord) elif nombre_de_turno == PC: if coord == "": pudo_jugar = self.play_pc() else: pudo_jugar = self.__tablero_g.set_piece(coord,color_de_turno,"blanco",audio, ventana) sonido_voltear = "voltear_negro" pc_manual = True if pudo_jugar: if coord == "": coord = self.get_last_pc_move() self.__tablero_g.set_coord_selected_cell(coord) if not pc_manual: if color_de_turno == board.BLANCO: pudo_jugar = self.__tablero_g.set_piece(coord,color_de_turno,"blanco",audio, ventana) sonido_voltear = "voltear_negro" else: pudo_jugar = self.__tablero_g.set_piece(coord,color_de_turno,"negro",audio, ventana) sonido_voltear = "voltear_blanco" marcador.render_numbers(self.__tablero,self.get_turn().get_color(),ventana) self.__print_log("PC jugo en: " + str(coord)) if pudo_jugar: audio.wait_sound_end() self.__tablero_g.do_line_animation(coord, color_de_turno, sonido_voltear, audio, marcador, ventana) else: pudo_jugar = True audio.play_voice_sound("game", "pasa_el_turno") audio.wait_sound_end() #extra = {"play_turn_sound":False} if pudo_jugar: if not self.is_over(): self.change_turn() self.update_possible_moves() if self.__con_jugadas_posibles: if extra == "" or (not extra == "" and not "update_possibles_moves" in extra): self.__tablero_g.lista_jugadas = self.__lista_jugadas_posibles if not extra == "": if not "change_score_color" in extra: marcador.render_all(self.__tablero,self.get_turn().get_color(),ventana) if not "play_turn_sound" in extra: audio.play_init_turn_sounds(self.__tablero_g,self) else: audio.play_init_turn_sounds(self.__tablero_g,self) marcador.render_all(self.__tablero,self.get_turn().get_color(),ventana) if self.__con_jugadas_posibles: self.__tablero_g.render_list_possible_moves(ventana) pygame.display.update() else: self.__lista_jugadas_posibles = [] if extra == "": self.__termino_juego = True marcador.render_all(self.__tablero,self.get_turn().get_color(),ventana) pygame.display.update() audio.play_end_game_sounds(self.__tablero_g,self) else: audio.play_end_game_sounds(self.__tablero_g,self) self.__termino_juego = True return pudo_jugar def game_ended(self): return self.__termino_juego def play_pc(self): return self.__make_a_move() def __make_a_move(self): if self.__pc.play(self.__tablero,self.__jugadores[self.__turno].get_color()): self.__ultima_jugada_pc = self.__pc.get_last_move() return True else: return False def get_player_by_color(self, color=board.BLANCO): for jugador in self.__jugadores: if jugador.get_color() == color: return jugador def get_player_by_name(self, nombre=PC): for jugador in self.__jugadores: if jugador.get_name() == nombre: return jugador def get_final_result(self): if self.__tablero.get_can_fichas_blancas() > self.__tablero.get_can_fichas_negras(): return self.get_player_by_color(board.BLANCO) elif self.__tablero.get_can_fichas_blancas() < self.__tablero.get_can_fichas_negras(): return self.get_player_by_color(board.NEGRO) else: return '' def get_last_pc_move(self): return self.__ultima_jugada_pc def get_last_human_move(self): return self.__ultima_jugada_humano def get_players(self): """ Retorna un vector con los datos de los jugadores.""" jugador1 = self.__jugadores[0] jugador2 = self.__jugadores[1] return [{'nombre':jugador1.get_name(),'color':jugador1.get_color()},{'nombre':jugador2.get_name(),'color':jugador2.get_color()}] def get_board_configuration(self): """ Retorna un diccionario con la configuracion actual del tablero.""" return {'dimension':self.__tablero.get_dimension(),'configuracion':self.__tablero.get_casillas()} def get_board(self): return self.__tablero def shorcut_lose_game(self): jug_humano = self.get_player_by_name(HUMANO) if jug_humano.get_color() == board.BLANCO: self.__tablero.set_can_fichas_blancas(0) self.__tablero.set_can_fichas_negras(1) else: self.__tablero.set_can_fichas_blancas(1) self.__tablero.set_can_fichas_negras(0) def shorcut_win_game(self): jug_humano = self.get_player_by_name(HUMANO) if jug_humano.get_color() == board.BLANCO: self.__tablero.set_can_fichas_blancas(1) self.__tablero.set_can_fichas_negras(0) else: self.__tablero.set_can_fichas_blancas(0) self.__tablero.set_can_fichas_negras(1) def shorcut_draw_game(self): self.__tablero.set_can_fichas_blancas(1) self.__tablero.set_can_fichas_negras(1) def get_list_possible_moves(self): return self.__lista_jugadas_posibles
class Game: def __init__(self, tablero, jugador1, jugador2, con_jugadas_posibles=True, nivel=Ai.FACIL, write_path=""): # self.__gui = Gui() # self.__tablero = self.__gui.init_board().get_board() self.__tablero_g = tablero self.__tablero = tablero.get_logical_board() # Iniciliazo la inteligencia para la PC self.__pc = Ai(nivel) # Inicializo un vector de jugadores self.__jugadores = [jugador1, jugador2] self.__ganador = "" self.__nro_turno = 0 self.__termino_juego = False self.__juego_mesh = False self.__con_jugadas_posibles = con_jugadas_posibles self.__lista_jugadas_posibles = [] if write_path != "": # Imprimo en el log la configuracion del juego que se inicia try: f = open(os.path.abspath(write_path + "/data/game.log"), "r") f.close() self.__log_file = open(os.path.abspath(write_path + "/data/game.log"), "a") print >> self.__log_file, "\nGAME LOG: " + time.asctime() except: self.__log_file = open(os.path.abspath(write_path + "/data/game.log"), "w") print >> self.__log_file, "GAME LOG: " + time.asctime() print >> self.__log_file, "Tablero: " + str(self.__tablero.get_dimension()) + "x" + str( self.__tablero.get_dimension() ) if jugador1.get_color() == board.BLANCO and jugador1.get_name() == PC: print >> self.__log_file, "PC: Blanco" print >> self.__log_file, "Jugador: Negro" elif jugador1.get_name() == HUMANO and jugador2.get_name() == HUMANO: if jugador1.get_color() == board.BLANCO: print >> self.__log_file, "Jugador1: Blanco" print >> self.__log_file, "Jugador2: Negro" else: print >> self.__log_file, "Jugador1: Negro" print >> self.__log_file, "Jugador2: Blanco" else: print >> self.__log_file, "PC: Negro" print >> self.__log_file, "Jugador: Blanco" def __del__(self): try: self.__log_file.close() except: log.debug("Problemas al cerrar el descriptor de archivo. (Game Class)") def get_game_log_file(self): return self.__log_file def get_turn(self): return self.__jugadores[self.__turno] def set_turn(self, jugador): if jugador.equal(self.__jugadores[0]): self.__turno = 0 elif jugador.equal(self.__jugadores[1]): self.__turno = 1 else: raise Exception("No se pudo asignar el turno, el jugador no existe! (Game Class)") self.update_possible_moves() def update_possible_moves(self): self.__lista_jugadas_posibles = Referee.possibles_moves(self.get_turn().get_color(), self.__tablero) def increase_turn_number(self): self.__nro_turno += 1 def get_turn_number(self): return self.__nro_turno def __next_turn(self): color = self.__jugadores[self.__turno].get_color() # Veo si hay jugada posible para el turno siguiente, es decir si era Blanco para el Negro if Referee.is_at_least_one_move(color * -1, self.__tablero): return True else: return False def with_possibles_moves(self): return self.__con_jugadas_posibles def change_turn(self): # if self.__next_turn(): self.__turno = (self.__turno - 1) * -1 self.increase_turn_number() # return True # else: # return False def is_over(self): if Referee.is_at_least_one_move(board.BLANCO, self.__tablero): return False elif Referee.is_at_least_one_move(board.NEGRO, self.__tablero): return False else: return True def init_next_turn(self): pass def __print_log(self, mensaje): try: print >> self.__log_file, mensaje except: print mensaje def get_mesh_game(self): return self.__juego_mesh def set_mesh_game(self, valor): self.__juego_mesh = valor def play(self, coord="", audio="", marcador="", ventana="", extra=""): pc_manual = False if not self.is_over(): jugadas_posibles_real = len(self.__lista_jugadas_posibles) self.__ultima_jugada_humano = "" if jugadas_posibles_real > 0: nombre_de_turno = self.get_turn().get_name() color_de_turno = self.get_turn().get_color() if nombre_de_turno == HUMANO or nombre_de_turno == VIRTUAL: if coord == "": coord = self.__tablero_g.get_coord_selected_cell() if color_de_turno == board.BLANCO: pudo_jugar = self.__tablero_g.set_piece(coord, color_de_turno, "blanco", audio, ventana) sonido_voltear = "voltear_negro" else: pudo_jugar = self.__tablero_g.set_piece(coord, color_de_turno, "negro", audio, ventana) sonido_voltear = "voltear_blanco" if pudo_jugar: marcador.render_numbers(self.__tablero, self.get_turn().get_color(), ventana) self.__ultima_jugada_humano = coord self.__print_log("JUGADOR jugo en: " + str(self.__ultima_jugada_humano)) if nombre_de_turno == VIRTUAL: self.__tablero_g.set_coord_selected_cell(coord) elif nombre_de_turno == PC: if coord == "": pudo_jugar = self.play_pc() else: pudo_jugar = self.__tablero_g.set_piece(coord, color_de_turno, "blanco", audio, ventana) sonido_voltear = "voltear_negro" pc_manual = True if pudo_jugar: if coord == "": coord = self.get_last_pc_move() self.__tablero_g.set_coord_selected_cell(coord) if not pc_manual: if color_de_turno == board.BLANCO: pudo_jugar = self.__tablero_g.set_piece(coord, color_de_turno, "blanco", audio, ventana) sonido_voltear = "voltear_negro" else: pudo_jugar = self.__tablero_g.set_piece(coord, color_de_turno, "negro", audio, ventana) sonido_voltear = "voltear_blanco" marcador.render_numbers(self.__tablero, self.get_turn().get_color(), ventana) self.__print_log("PC jugo en: " + str(coord)) if pudo_jugar: audio.wait_sound_end() self.__tablero_g.do_line_animation(coord, color_de_turno, sonido_voltear, audio, marcador, ventana) else: pudo_jugar = True audio.play_voice_sound("game", "pasa_el_turno") audio.wait_sound_end() # extra = {"play_turn_sound":False} if pudo_jugar: if not self.is_over(): self.change_turn() self.update_possible_moves() if self.__con_jugadas_posibles: if extra == "" or (not extra == "" and not "update_possibles_moves" in extra): self.__tablero_g.lista_jugadas = self.__lista_jugadas_posibles if not extra == "": if not "change_score_color" in extra: marcador.render_all(self.__tablero, self.get_turn().get_color(), ventana) if not "play_turn_sound" in extra: audio.play_init_turn_sounds(self.__tablero_g, self) else: audio.play_init_turn_sounds(self.__tablero_g, self) marcador.render_all(self.__tablero, self.get_turn().get_color(), ventana) if self.__con_jugadas_posibles: self.__tablero_g.render_list_possible_moves(ventana) pygame.display.update() else: self.__lista_jugadas_posibles = [] if extra == "": self.__termino_juego = True marcador.render_all(self.__tablero, self.get_turn().get_color(), ventana) pygame.display.update() audio.play_end_game_sounds(self.__tablero_g, self) else: audio.play_end_game_sounds(self.__tablero_g, self) self.__termino_juego = True return pudo_jugar def game_ended(self): return self.__termino_juego def play_pc(self): return self.__make_a_move() def __make_a_move(self): if self.__pc.play(self.__tablero, self.__jugadores[self.__turno].get_color()): self.__ultima_jugada_pc = self.__pc.get_last_move() return True else: return False def get_player_by_color(self, color=board.BLANCO): for jugador in self.__jugadores: if jugador.get_color() == color: return jugador def get_player_by_name(self, nombre=PC): for jugador in self.__jugadores: if jugador.get_name() == nombre: return jugador def get_final_result(self): if self.__tablero.get_can_fichas_blancas() > self.__tablero.get_can_fichas_negras(): return self.get_player_by_color(board.BLANCO) elif self.__tablero.get_can_fichas_blancas() < self.__tablero.get_can_fichas_negras(): return self.get_player_by_color(board.NEGRO) else: return "" def get_last_pc_move(self): return self.__ultima_jugada_pc def get_last_human_move(self): return self.__ultima_jugada_humano def get_players(self): """ Retorna un vector con los datos de los jugadores.""" jugador1 = self.__jugadores[0] jugador2 = self.__jugadores[1] return [ {"nombre": jugador1.get_name(), "color": jugador1.get_color()}, {"nombre": jugador2.get_name(), "color": jugador2.get_color()}, ] def get_board_configuration(self): """ Retorna un diccionario con la configuracion actual del tablero.""" return {"dimension": self.__tablero.get_dimension(), "configuracion": self.__tablero.get_casillas()} def get_board(self): return self.__tablero def shorcut_lose_game(self): jug_humano = self.get_player_by_name(HUMANO) if jug_humano.get_color() == board.BLANCO: self.__tablero.set_can_fichas_blancas(0) self.__tablero.set_can_fichas_negras(1) else: self.__tablero.set_can_fichas_blancas(1) self.__tablero.set_can_fichas_negras(0) def shorcut_win_game(self): jug_humano = self.get_player_by_name(HUMANO) if jug_humano.get_color() == board.BLANCO: self.__tablero.set_can_fichas_blancas(1) self.__tablero.set_can_fichas_negras(0) else: self.__tablero.set_can_fichas_blancas(0) self.__tablero.set_can_fichas_negras(1) def shorcut_draw_game(self): self.__tablero.set_can_fichas_blancas(1) self.__tablero.set_can_fichas_negras(1) def get_list_possible_moves(self): return self.__lista_jugadas_posibles
class MainGUI: def __init__(self): pygame.init() self.manager = GameManager() self.enemy = Ai() pygame.display.set_caption("Tic Tac Toe") self.WIDTH = 540 self.HEIGHT = 540 self.screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT)) self.background = pygame.Surface((self.WIDTH, self.HEIGHT)) self.background.fill(pygame.Color('#E3E3E3')) # FONTS self.playerFont = pygame.font.SysFont('arial', 70) self.resultFont = pygame.font.SysFont('arial', 60, bold=True) self.infoFont = pygame.font.SysFont('arial', 30, italic=True) # define cell dimensions self.cellWidth = self.WIDTH / 3 self.cellHeight = self.HEIGHT / 3 self.board = [] # to create the 3x3 grid for i in range(3): for j in range(3): self.board.append( Cell(self.cellWidth * i, self.cellHeight * j, self.cellWidth, self.cellHeight)) self.manager.gameState = 'progress' self.running = True def displayGrids(self): # horizontal lines for i in range(2): # pygame.draw.line(surface, color, start_pos, end_pos, width = 1) start_pos = (0, int(self.cellHeight * (i + 1))) end_pos = (self.WIDTH, int(self.cellHeight * (i + 1))) pygame.draw.line(self.background, (0, 0, 0), start_pos, end_pos, 2) # vertical lines for i in range(2): # pygame.draw.line(surface, color, start_pos, end_pos, width = 1) start_pos = (int(self.cellWidth * (i + 1)), 0) end_pos = (int(self.cellWidth * (i + 1)), self.HEIGHT) pygame.draw.line(self.background, (0, 0, 0), start_pos, end_pos, 2) for cell in self.board: player = self.playerFont.render(cell.state, True, (0, 0, 0)) x, y = self.playerFont.size(cell.state) self.screen.blit( player, (int((cell.x + cell.w / 2) - x / 2), int((cell.y + cell.h / 2) - y / 2))) def endGameMsg(self, result): # rectangle that the message will be drawn w = self.WIDTH h = 150 x = 0 y = int(self.HEIGHT / 2 - h / 2) pygame.draw.rect(self.screen, pygame.Color( '#4D4D4D'), pygame.Rect(x, y, w, h)) # result text if self.manager.result == 'tie': resultText = "It's a tie!" result = self.resultFont.render(resultText, True, (0, 0, 0)) else: resultText = f"{self.manager.result} won!" result = self.resultFont.render(resultText, True, (0, 0, 0)) x, y_txt = self.resultFont.size(resultText) self.screen.blit(result, (int(w / 2 - x / 2), int(y + 5))) # info text infoText = "Press R to restart the game!" info = self.infoFont.render(infoText, True, (0, 0, 0)) x, y_txt = self.infoFont.size(infoText) self.screen.blit(info, (int(w / 2 - x / 2), int(y + 100))) def run(self): while self.running: for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False # check mouse down if event.type == pygame.MOUSEBUTTONDOWN: if self.manager.gameState == 'progress': for cell in self.board: if self.manager.currentPlayer == 'X' and cell.checkUserCLicked(pygame.mouse.get_pos()) and cell.state == '': # cause the O player is the AI cell.changeState('X') self.manager.changeTurn() # check keys pressed if event.type == pygame.KEYDOWN: # restart the game if event.key == pygame.K_r and self.manager.gameState == 'over': self.manager.currentPlayer = 'X' for cell in self.board: cell.state = '' self.manager.gameState = 'progress' # recolorize the background self.background.fill(pygame.Color('#ffffff')) # to check if there's a win if self.manager.checkWin(self.board): self.manager.currentPlayer = '' self.manager.gameState = 'over' self.manager.result = self.manager.checkWin(self.board, True) # to check if there's a tie if self.manager.checkTie(self.board): self.manager.currentPlayer = '' self.manager.gameState = 'over' self.manager.result = 'tie' # check if it's AI turn if self.manager.currentPlayer == 'O' and self.manager.gameState == 'progress': self.enemy.play(self.board) self.manager.changeTurn() # UI self.screen.blit(self.background, (0, 0)) if self.manager.gameState == 'over': # if tie, paint te background gray if self.manager.result == 'tie': self.background.fill(pygame.Color('#9DA897')) elif self.manager.result == 'X': self.background.fill(pygame.Color('#7AFF77')) elif self.manager.result == 'O': self.background.fill(pygame.Color('#F53920')) self.displayGrids() self.endGameMsg(self.manager.result) if self.manager.gameState != 'over': self.displayGrids() pygame.display.update()