def select_node(root): nodes = list(filter(lambda node: node.score == root.score, root.leaves)) for node in nodes: w_score, b_score = total_score(node.board) node.score = w_score - b_score return max(nodes, key=lambda node: node.score) if root.color == "w" else min( nodes, key=lambda node: node.score)
def play(self): """plays AI's move""" print self.name + " is thinking..." ## if AI plays first move if not self.game.played: space = 'right' letters = '' max_length = 7 row = 7 col = 7 simple_areas = ((space, letters, max_length, row, col),) else: simple_areas = self.simple_area(self.game.board) ## simple_areas contains: space, letters, max_length, row, col ## check_area returns: to_play, to_score, word_list, fails, side, dirn ## this determines where the AI can play for area in simple_areas: space, letters, max_length, row, col = area tup = check_area(area) if tup: to_play, to_score, word_list, fails, side, dirn = tup break else: continue ## if AI can't find word, swap or pass if fails or not to_play: if self.game.bag.num_letters_left() >= 7: num = 7 else: num = self.game.bag.num_letters_left() try: self.swap(self.rack()[:num]) print '\n' + self.name + " swaps " + str(num) + " letters!\n" except NotEnoughLettersInBagError: print '\n' + self.name + " passes!" return ## score and play word on board score = total_score(to_score, word_list, row, col, dirn, self.game.board) self.score += score print('\n' + self.name + ' played ' + to_play + ' for %i points!\n' % score) self.game.board.place_word(to_play.upper(), row, col, dirn) used = list(to_score.replace('*', '')) self.rack.use(used) self.game.played = True
def main(): #! def timeout_handler(signum, frame): #! raise TimeoutException() #! signal.signal(signal.SIGALRM, timeout_handler) #! signal.alarm(20) # trigger alarm in 20 seconds ## load starting screen pregame_board = Board() pregame_board.empty_board() pregame_board.place_word('PYTHON', 5, 4, 'right') pregame_board.place_word('SCRABBLE', 6, 4, 'right') pregame_board.place_word('GAME', 7, 4, 'right') pregame_board.place_word('AMEYA', 13, 0, 'right') pregame_board.place_word('PATHARE', 13, 6, 'right') pregame_board.place_word('MIKE', 14, 0, 'right') pregame_board.place_word('PATTERSON', 14, 5, 'right') pregame_board.display_compact() ## ask to load game or start a new game while True: response = raw_input("Start new game(new) or load saved game(load)? ") if response == 'new' or response == 'load': break else: print "Please enter 'new' or 'load' " ## ask to display compact or not while True: resp = raw_input("Compact display? ") compact = True if resp == 'no': compact = False break elif resp == 'yes': compact = True break else: print "Please enter 'yes' or 'no'" ## set up new game if response == 'new': ## ask for number of players and computers while True: num_players = 0 num_computers = 0 try: num_players = int(raw_input("How many players? ")) num_computers = int(raw_input("How many computers? ")) except ValueError: print "Please enter a number." continue if (num_players + num_computers < 2) or \ num_players + num_computers > 4: print "Invalid number of players and computers: " + \ str(num_players + num_computers) else: break ## ask for player/AI names player_names = [] for num in xrange(int(num_players)): player_names.append(raw_input("What is the name of player " + str(num + 1) + "? ")) computer_names = {} for num in xrange(int(num_computers)): dif = 'easy' while True: dif = raw_input("What is the difficulty of AI_" + \ str(num + 1) + "? ") if dif == 'easy' or dif == 'hard': break else: print "Please enter 'easy' or 'hard'" computer_names['AI_' + str(num + 1)] = dif game = Game(player_names, computer_names) ## load saved game if response == 'load': game_state, game_players, game_comps = load_game() game_comps_dict = {} for comp in game_comps: game_comps_dict[comp] = game_comps[comp][2] game = Game(game_players.keys(), game_comps_dict) game.played = True game.bag = Bag(game_state[0]) game.board = Board(game_state[1]) game.player_order = game_state[2] game.turn = game_state[3] for player in game.players: if game.players[player].isAI: game.players[player] = AI(player, game, game_comps_dict[player], \ rack=game_comps[player][0], \ score=game_comps[player][1]) else: game.players[player] = Player(player, game, \ rack=game_players[player][0], \ score=game_players[player][1]) ####### MAIN GAME LOOP ####### while True: ## determine current player curr_player = game.player_order[game.turn % len(game.player_order)] ## if AI, make AI play if game.players[curr_player].isAI: #! try: TAB BELOW #game.display_player_screen(compact)##remove print 'letters left: ', int(game.bag.num_letters_left()) game.players[curr_player].play() game.turn += 1 if len(game.players[curr_player].rack()) == 0 and \ len(game.bag()) == 0: break else: continue #! except TimeoutException: #! game.turn += 1 else: game.display_player_screen(compact) ## prompt player with options (pass, play, swap, shuffle, quit, save) while True: move = raw_input("play, pass, swap, shuffle, quit, or save?\n" + \ "Enter move: ") if move == "play" or \ move == "pass" or \ move == "swap" or \ move == "shuffle" or \ move == "quit" or \ move == "save" or \ move == "place" or \ move == "set rack" or \ move == "set bag": # place, set rack, set bag only for testing break else: print "\nPlease enter valid move." ## handle user input if move == "pass": game.turn += 1 if move == "swap": while True: to_swap = raw_input("Please enter the letters you wish to" + \ " swap without spaces: ") if not re.match(r'[a-zA-Z_]{1,7}', to_swap): print "Invalid input" else: try: game.players[curr_player].swap(to_swap) game.turn += 1 except LetterNotInRackError: print "Letters not in rack" continue except NotEnoughLettersInBagError: print "Not enough letters in bag to swap" continue break if move == "shuffle": game.players[curr_player].shuffle() if move == "quit": ans = raw_input("This will end the game, are you sure you want" + " to quit? ") if ans == 'y' or ans == 'yes' or ans == 'yea': game.is_over = True print curr_player + " quit!\n" print curr_player.upper() + " LOSES!" del game.players[curr_player] for player in game.players: print player.upper() + " WINS!" return else: continue if move == "save": game.save_game() print "Game Saved." return if move == "play": went_back = False while True: # allow back option resp = raw_input("Press Enter to continue, or (b) to go back ") if resp == 'b': went_back = True break # get row col and direction from user resp = raw_input("Please enter row and col of beginning letter" + \ ", and the direction(right or down)\n" + \ "row col direction: ") resp = resp.split() # check for bad input try: row = resp[0] col = resp[1] dirn = resp[2] except IndexError: print "Please enter 3 arguments with spaces inbetween" continue try: row = int(row) col = int(col) except ValueError: print "Please enter a number" continue if row > 14 or col > 14 or row < 0 or col < 0: print "Invalid location" continue if dirn != 'right' and dirn != 'down': print "Please enter 'right' or 'down'" continue # get word to be played word = raw_input("Enter the word you want to place using\n" + \ "* to replace letters on the board. (i.e. if r is\n" + \ "on the board and marks is what you want to place\n" + \ "then type ma*ks): ") # check for bad input if dirn == 'down': if row + len(word) > 15: print "Word will extend beyond board" continue if dirn == 'right': if col + len(word) > 15: print "Word will extend beyond board" continue word = word.upper() # Ensure that the letters used are in the rack try: compare_to_rack(word, game.players[curr_player].rack) except LetterNotInRackError: print "Letters not in rack" continue # Replaces blank tiles with a letter chosen by the user o_word = word if '_' in word: o_word = replace_blank(word) # Get the words that were just made by the placed tiles word_list = check_sides(o_word, row, col, dirn, game.board, game.played) # Ensure the word connects to at least one other word if game.played and not word_list and '*' not in o_word: print 'The word must connect to a word on the board.' continue # Ensure the first word gets played in the middle if not game.played: if row == 7 and dirn == 'right': if col <= 7 and col + len(o_word) >= 7: pass else: print "First word must start in center" continue elif col == 7 and dirn == 'down': if row <= 7 and row + len(o_word) >= 7: pass else: print "First word must start in center" continue else: print "First word must start in center" continue # Replace *'s with the character on the board o_word = orig_word(o_word, row, col, dirn, game.board) # Add intended word to word_list word_list.append(o_word) print "word_list final = ", word_list # Create a list of failed words if they exist # Print the failed words for the user to try again fails = check_words(word_list, game.dictionary) if fails: for word in fails: print word print 'The above words were not in the dictionary' continue break # if user went back don't execute the rest of the code if went_back: continue # now that we know the input is valid, # score and place the word on the board score = total_score(word, word_list, row, col, dirn, game.board) game.players[curr_player].score += score print('\n' + curr_player + " got " + str(score) + " points!\n") game.board.place_word(o_word, row, col, dirn) used = [] for letter in word: if letter != '*': used.append(letter) game.players[curr_player].rack.use(used) game.played = True game.turn += 1 if len(game.players[curr_player].rack()) == 0 and \ len(game.bag()) == 0: break ## Admin Controls if move == 'place': resp = raw_input("Enter row col dirn word ") resp = resp.split(' ') game.board.place_word(resp[3].upper(), int(resp[0]), int(resp[1]), resp[2]) if move == 'set rack': resp = raw_input("Enter player rack ") r = resp.split(' ') game.players[r[0]].rack = Rack(game.bag, r[1:]) if move == 'set bag': resp = raw_input("Enter new bag ") r = resp.split(' ') game.bag.set_bag(r) ##### END MAIN GAME LOOP ##### ## print winner winner = game.players[curr_player] for player in game.players.values(): if player.get_score() > winner.get_score(): winner = player for player in game.players: game.players[player].display() print winner.get_name().upper() + " WON!"