コード例 #1
0
def choose_board_layout(player):
    """
    Board is stored as a list of lists.
    List is gv.CHESSBOARD[file_][rank].
    Each square contains a single character, either ' '
    or one of the characters representing a piece.
    Defender's pieces are upper-case, attackers are 
    lower-case.
    """
    global NRANKS, NFILES

    gv.prnt('{0}, choose the board layout.'.format(player))
    gv.prnt('You must have 8 ranks.')
    gv.UI.clear_inv_choices()
    gv.UI.set_inv_choice({"Please enter a number": lambda x: not x.isdigit()})
    gv.UI.set_inv_choice({
        "You can only have whole numbers of files!":
        lambda x: math.fmod(float(x), 1)
    })
    gv.UI.set_inv_choice(
        {"Can't have more than 8 files.": lambda x: int(x) > 8})
    gv.UI.set_inv_choice(
        {"Can't have less than 2 files.": lambda x: int(x) < 2})

    NFILES = int(
        gv.UI.user_input_check_choices(
            "How many files would you like (2 to 8)?",
            player=player,
        ))

    gv.CHESSBOARD = []
    for i in xrange(NFILES):
        gv.CHESSBOARD += [[' '] * NRANKS]

    print_board('all', clear=True)
コード例 #2
0
def process_build_turn():
    gv.N_REINFORCE_ARMIES = count_army_allowance()

    while gv.N_REINFORCE_ARMIES > 0:
        save.checkpoint('during_build_turn')
        gv.prnt("You have " + str(gv.N_REINFORCE_ARMIES) + " armies to place.")
        gv.N_REINFORCE_ARMIES = reinforce_a_territory(gv.N_REINFORCE_ARMIES)
コード例 #3
0
def manualsave(filename):
    """ Since we have a finite set of restore points, a manual save
    is just renaming the autosave such that it is kept.
    """
    shutil.copy2(os.path.join('saves', 'autosave'),
                 os.path.join('saves', filename))
    gv.prnt('Game saved as %s.' % filename)
コード例 #4
0
def choose_placement(player_type, player, pieces):
    unplaced_pieces = deepcopy(pieces)

    if player_type == 'attacker':
        gv.prnt('As the attacker, you start in the top half of the board:')
        board_part = 'top'
        valid_ranks = '[0-3]'
    elif player_type == 'defender':
        board_part = 'bottom'
        valid_ranks = '[4-7]'
    else:
        raise Exception('Invalid player_type.')

    while unplaced_pieces:
        gv.prnt('As the {}, you start in the {} half of the board:'.format(
            player_type, board_part),
                clear=True)
        print_board(board_part)

        gv.UI.clear_inv_choices()
        gv.UI.set_inv_choice({
            "Choose from {0}.".format(unplaced_pieces):
            lambda x: x not in unplaced_pieces
        })

        piece = gv.UI.user_input_check_choices(
            '{0}: choose a piece to place from:'
            '\n{1}\n'.format(player, unplaced_pieces),
            player=player)

        max_file = chr(NFILES + 96)

        gv.UI.clear_inv_choices()
        gv.UI.set_inv_choice({
            "Invalid choice.\nPlease enter a string of the "
            "form XY with X in [A-{0}a-{1}] and Y in {2}.".format(
                max_file.upper(), max_file.lower(), valid_ranks):
            lambda x: not re.match(
                r'[a-{0}]{1}'.format(max_file.lower(), valid_ranks), x)
        })

        pos = gv.UI.user_input_check_choices(
            'Please choose square, example: "G3"', player=player)

        file_, rank = coords(pos)
        if gv.CHESSBOARD[file_][rank] != ' ':
            gv.prnt("There's already a piece there, try again")
            continue

        if player_type == 'attacker':
            piece_symbol = piece.lower()
        elif player_type == 'defender':
            piece_symbol = piece.upper()
        gv.CHESSBOARD[file_][rank] = piece_symbol
        unplaced_pieces.remove(piece)

    gv.prnt(('---------------YOUR FINAL LAYOUT---------------'))
    print_board(board_part)
    gv.prnt(('-----------------------------------------------'))
コード例 #5
0
def process_attack_turn():
    save.checkpoint('start_of_attack_turn')
    if not attackable_neighbours_exist() and not gv.RESTORING:
        gv.prnt("Not possible to attack! Build instead.")
        process_build_turn()

    while attackable_neighbours_exist() or gv.RESTORING:
        if not gv.RESTORING:
            gv.ATTACK_FROM = choose_attack_from()
            gv.ATTACK_TO = choose_attack_to()
            gv.N_ATTACK_ARMIES = choose_narmies_to_attack_with()
            gv.N_DEFEND_ARMIES = gv.TERRITORIES[gv.ATTACK_TO].narmies
            gv.DEFENDER = gv.TERRITORIES[gv.ATTACK_TO].owner
        else:
            gv.ATTACK_FROM = gv.SAVED_GLOBALS['ATTACK_FROM']
            gv.ATTACK_TO = gv.SAVED_GLOBALS['ATTACK_TO']
            gv.N_ATTACK_ARMIES = gv.SAVED_GLOBALS['N_ATTACK_ARMIES']
            gv.N_DEFEND_ARMIES = gv.SAVED_GLOBALS['N_DEFEND_ARMIES']
            gv.DEFENDER = gv.SAVED_GLOBALS['DEFENDER']
            gv.CURR_PLAYER = gv.SAVED_GLOBALS['CURR_PLAYER']
        gv.prnt.clear_output()
        gv.prnt('\n===================================\n'
                '{} is attacking {} at {} with {} armies from {}!\n'
                'The defender has {} armies.\n'
                '===================================\n\n'.format(
                    gv.CURR_PLAYER,
                    gv.DEFENDER,
                    gv.ATTACK_TO,
                    gv.N_ATTACK_ARMIES,
                    gv.ATTACK_FROM,
                    gv.N_DEFEND_ARMIES,
                ))
        narmies_attacker, narmies_defender = chess.play_chess(
            gv.N_ATTACK_ARMIES, gv.N_DEFEND_ARMIES, gv.CURR_PLAYER,
            gv.DEFENDER)
        if narmies_defender == 0:
            gv.prnt("{0} defeated!".format(gv.TERRITORIES[gv.ATTACK_TO].owner))
            gv.TERRITORIES[gv.ATTACK_FROM].narmies -= gv.N_ATTACK_ARMIES
            gv.TERRITORIES[gv.ATTACK_TO].narmies = narmies_attacker
            gv.TERRITORIES[gv.ATTACK_TO].reassign_owner(gv.CURR_PLAYER)
        else:
            gv.prnt("{0} repelled!".format(gv.CURR_PLAYER))
            gv.TERRITORIES[gv.ATTACK_FROM].narmies -= \
                                gv.N_ATTACK_ARMIES - narmies_attacker
            gv.TERRITORIES[gv.ATTACK_TO].narmies = narmies_defender

        gv.UI.handle_user_input('<press enter>')
        save.checkpoint('after_battle')
        gv.BOARD.print_board()

        gv.prnt("Continue to attack, (y)es or (n)o?")
        attack_some_more = False
        while attack_some_more is False:
            response = gv.UI.handle_user_input('continue: ')
            if response in ['y', 'yes']:
                attack_some_more = True
            if response in ['n', 'no']:
                return 'Chickened out'
コード例 #6
0
def attackable_neighbours_exist():
    able_to_attack = False
    for unused_key, territory in gv.TERRITORIES.items():
        if territory.owner == gv.CURR_PLAYER and territory.narmies > 1:
            for neighbour in territory.neighbours:
                if neighbour.owner != gv.CURR_PLAYER:
                    able_to_attack = True
    if not able_to_attack:
        gv.prnt("No possiblities for attack!")
    return able_to_attack
コード例 #7
0
def restore_saved_globals():
    # Do some experimenting to ensure this works as expected - particularly with regards to scope.
    if gv.DEBUG:
        pprint(gv.SAVED_GLOBALS)
    restore_saved_globals_into_module(gv, gv.SAVED_GLOBALS)

    gv.BOARD.print_board()
    if gv.ATTACK_FROM and gv.ATTACK_TO:
        gv.prnt("{} is attacking from {} to {} with {} armies".format(
            gv.CURR_PLAYER, gv.ATTACK_FROM, gv.ATTACK_TO, gv.N_ATTACK_ARMIES))
コード例 #8
0
 def handle_user_input(self,
                       message,
                       cast_lower=True,
                       clear=False,
                       player=None):
     # By default, the player whose turn it is makes the input.
     # We need to know who is inputting, so we know which bot to run for AI.
     player = player or gv.CURR_PLAYER
     if gv.RESTORING:
         if gv.DEBUG:
             gv.prnt(message)
         user_input = fake_user_input_during_restore(message)
     elif gv.HEADLESS:
         gv.prnt(message, clear=clear)
         user_input = fake_user_input_from_http(message)
     else:
         if message != '':
             gv.prnt(message, clear=clear)
         user_input = None
         while user_input in [None]:
             gv.prnt('>>')
             curr_player = gv.PLAYERS.get(player)
             if gv.HEADLESS:
                 input_func = sys.stdin.readline
             elif curr_player is not None and curr_player.is_ai:
                 # If this is an AI player, dispatch to its turn processing methods
                 # This returns a function that, when called, returns the desired string
                 input_func = curr_player.ai_instance.dispatch_message(
                     message, gv)
             else:
                 input_func = raw_input
             # if cast_lower:
             #     user_input = sys.stdin.readline()
             # else:
             #     user_input = input_func()
             user_input = input_func()
             if cast_lower:
                 user_input = user_input.lower()
             if curr_player is not None and curr_player.is_ai:
                 gv.prnt(user_input, clear=False)
         if user_input in ['exit', 'x']:
             raise UserQuitException
         if user_input in ['s', 'save']:
             temp_inv_choices = self.inv_choices
             self.clear_inv_choices()
             handle_save_request()
             self.inv_choices = temp_inv_choices
             self.user_input_check_choices(message)
         if user_input in ['l', 'load']:
             raise LoadException
     return user_input
コード例 #9
0
def eliminate_dead_players():
    if gv.RESTORING:
        for player in gv.PLAYERS.keys():
            if count_owned_territories(player) == 0:
                gv.prnt("{0} is out!".format(player))

                # A hook that can get called if the player has lost.
                if (hasattr(gv.PLAYERS[player], 'lose')
                        and callable(gv.PLAYERS[player].lose)):
                    gv.PLAYERS[player].lose()

                del gv.PLAYERS[player]
    else:
        pass
コード例 #10
0
def run_game(answer_queue, response_queue, worker=False, game_id=''):
    gv._AQ = answer_queue
    gv._RQ = response_queue
    gv.HEADLESS = worker
    gv.GAME_ID = game_id
    try:
        try:
            setup_game()
            main_loop()
        except utils.LoadException:
            restore_saved_game()
    except utils.UserQuitException:
        save.save('last_quit')
        gv.prnt("Byeeee!")
        sys.exit(0)
コード例 #11
0
def choose_attack_to():
    gv.prnt("Choose territory to attack, from the following list:")

    attack_to_list = []
    for territory in gv.TERRITORIES[gv.ATTACK_FROM].neighbours:
        if territory.owner != gv.CURR_PLAYER:
            gv.prnt(territory.name)
            attack_to_list.append(territory.lname)

    gv.UI.clear_inv_choices()
    gv.UI.set_inv_choice({
        "Can't attack there, choose again!":
        lambda x: x not in attack_to_list
    })

    return gv.UI.user_input_check_choices('to: ')
コード例 #12
0
def check_for_victory():
    if gv.RESTORING:
        return False
    else:
        if len(gv.PLAYERS) == 1:
            winner = gv.PLAYERS.keys()[0]
            gv.prnt("{0} wins!".format(winner))

            # A hook that can get called if the player has won.
            if (hasattr(gv.PLAYERS[winner], 'win')
                    and callable(gv.PLAYERS[winner].win)):
                gv.PLAYERS[winner].win()

            return True
        else:
            return False
コード例 #13
0
def risk_style(n_attack_armies, n_defend_armies, attacker, defender):
    continue_fight = True
    while continue_fight:
        attack_dice = []
        defend_dice = []
        for i in range(min(n_attack_armies, 3)):
            attack_dice.append(random.randint(1, 6))
        for i in range(min(n_defend_armies, 2)):
            defend_dice.append(random.randint(1, 6))

        gv.UI.handle_user_input("{0}, press enter to roll:".format(attacker),
                                player=attacker)
        for attd in attack_dice:
            gv.UI.handle_user_input("{0}".format(attd), player=attacker)
            if gv.AI_PLAYERS_ARE_PLAYING:
                sleep(gv.AI_PRINT_DELAY)
        gv.UI.handle_user_input("{0}, press enter to roll:".format(defender))
        for defd in defend_dice:
            gv.UI.handle_user_input("{0}".format(defd), player=defender)
            if gv.AI_PLAYERS_ARE_PLAYING:
                sleep(gv.AI_PRINT_DELAY)

        defend_dice.sort(reverse=True)
        attack_dice.sort(reverse=True)

        for dice in xrange(min(n_attack_armies, n_defend_armies, 2)):
            if attack_dice[dice] > defend_dice[dice]:
                n_defend_armies = max(n_defend_armies - 1, 0)
            else:
                n_attack_armies = max(n_attack_armies - 1, 0)

        gv.prnt("{0}: {1}".format(attacker, str(n_attack_armies)))
        gv.prnt("{0}: {1}".format(defender, str(n_defend_armies)))
        if n_attack_armies == 0 or n_defend_armies == 0:
            continue_fight = False

        if continue_fight:
            carry_on = gv.UI.handle_user_input(
                "Continue the battle, (y)es or (n)o?")
            if carry_on in ['y', 'yes']:
                continue_fight = True
                gv.prnt.clear_output()
            elif carry_on in ['n', 'no']:
                continue_fight = False

    return n_attack_armies, n_defend_armies
コード例 #14
0
def choose_narmies_to_attack_with():
    gv.prnt("There are " + str(gv.TERRITORIES[gv.ATTACK_FROM].narmies - 1) +
            " armies available for attack.")

    gv.UI.clear_inv_choices()
    gv.UI.set_inv_choice({"Please enter a number": lambda x: not x.isdigit()})
    gv.UI.set_inv_choice({
        "You can only have whole numbers of armies!":
        lambda x: math.fmod(float(x), 1)
    })
    gv.UI.set_inv_choice({
        "You must leave at least one army at home, try again!":
        lambda x: int(x) >= gv.TERRITORIES[gv.ATTACK_FROM].narmies
    })

    return int(
        gv.UI.user_input_check_choices(
            "Choose number of armies to attack with:"))
コード例 #15
0
def choose_attack_from():
    gv.prnt("Choose territory to attack from, from the following list:")

    attack_from_list = []
    for territory in gv.TERRITORIES.values():
        if territory.owner == gv.CURR_PLAYER and territory.narmies > 1:
            for neighbour in territory.neighbours:
                if neighbour.owner != gv.CURR_PLAYER:
                    gv.prnt(territory.name)
                    attack_from_list.append(territory.lname)
                    break

    gv.UI.clear_inv_choices()
    gv.UI.set_inv_choice({
        "Can't attack from there, choose again!":
        lambda x: x not in attack_from_list
    })

    return gv.UI.user_input_check_choices('from: ')
コード例 #16
0
    def print_board(self):
        w = 10.
        gv.prnt(' ' * int(float(self.ncols) * (w + 1.) / 2. - 8.) +
                "~~~ The World ~~~",
                clear=True)

        for row in xrange(self.nrows):
            subrows = [''] * 4

            for col in xrange(self.ncols):
                mark = gv.PLAYERS[self.territory_array[row][col].owner].colour

                namelen = min(len(self.territory_array[row][col].name),
                              int(w - 2.))
                namestring = self.territory_array[row][col].name[0:namelen]

                ownerlen = min(len(self.territory_array[row][col].owner),
                               int(w - 2.))
                ownerstring = self.territory_array[row][col].owner[0:ownerlen]

                armystring = str(
                    min(self.territory_array[row][col].narmies,
                        10**int(w - 2)))
                armylen = len(armystring)

                lpad = lambda x: mark * int(
                    math.floor((w - float(x)) / 2.) - 1)
                rpad = lambda x: mark * int(math.ceil((w - float(x)) / 2.) - 1)

                subrows[0] += '+' + '-' * int(w)
                subrows[1] += '|' + lpad(
                    namelen) + ' ' + namestring + ' ' + rpad(namelen)
                subrows[2] += '|' + lpad(
                    armylen) + ' ' + armystring + ' ' + rpad(armylen)
                subrows[3] += '|' + lpad(
                    ownerlen) + ' ' + ownerstring + ' ' + rpad(ownerlen)

            subrows[0] += '+'

            for isr in xrange(1, 4):
                subrows[isr] += '|'

            for subrow in subrows:
                gv.prnt(subrow)

        gv.prnt(('+' + '-' * int(w)) * self.ncols + '+')

        gv.prnt(' ' * int(float(self.ncols) * (w + 1.) / 2. - 8.) +
                "~~~~~~~~~~~~~~~~~")
        if gv.AI_PLAYERS_ARE_PLAYING:
            sleep(gv.AI_PRINT_DELAY)
コード例 #17
0
def pre_round():
    gv.ROUND_NUMBER += 1
    save.checkpoint('round_start')

    gv.prnt("------------------------")
    gv.prnt("- Round: " + str(gv.ROUND_NUMBER) + "-")
    gv.prnt("------------------------")
    gv.BOARD.print_board()
コード例 #18
0
 def user_input_check_choices(self, message, clear=False, player=None):
     if gv.RESTORING:
         user_input = fake_user_input_during_restore(message)
     elif gv.HEADLESS:
         gv.prnt(message, clear=clear)
         user_input = fake_user_input_from_http(message)
     else:
         valid_choice = False
         while valid_choice == False:
             user_input = self.handle_user_input(message,
                                                 clear=clear,
                                                 player=player)
             valid_choice = True
             if user_input == '':
                 valid_choice = False
                 continue
             for warning, condition in self.inv_choices.items():
                 if gv.DEBUG:
                     gv.prnt(warning, '*******', clear=False)
                 if condition(user_input):
                     gv.prnt(warning, clear=False)
                     valid_choice = False
                     break
     return user_input
コード例 #19
0
def process_move(player_type, player, opponents_pieces):

    print_board('all', clear=True)

    if gv.CHECK[player_type]:
        gv.prnt('~~~ CHECK! ~~~')

    # If it's the attacker's turn,
    # give them the option to withdraw.
    if player_type == 'attacker':
        withdraw_string = " or 'w' to withdraw"
    elif player_type == 'defender':
        withdraw_string = ""
    else:
        raise Exception('Invalid player type')


#    max_rank = chr(len(chessboard[0])+97)

# Check whether there are any valid moves for this player
    if not all_valid_moves(player_type):
        gv.UI.clear_inv_choices()
        gv.UI.set_inv_choice({
            "Please enter either 'w' or 'd'":
            lambda x: x not in ['w', 'd', 'withdraw', 'do nothing']
        })
        pos = gv.UI.user_input_check_choices(
            "{0}, you have no valid moves available,"
            "enter 'd' to do nothing{1}.".format(player, withdraw_string),
            player=player)
        if pos in ['w', 'withdraw']:
            return 'withdraw'
        else:
            return False

    valid_squares = get_coords_by_player_type(player_type)

    # Get the player's choice of piece to move & calculate valid moves
    valid_moves = None
    while not valid_moves:
        gv.UI.clear_inv_choices()
        if player_type == 'attacker':
            gv.UI.set_inv_choice({
                "No piece at that position!":
                lambda x: coords(x) not in valid_squares and x not in
                ['w', 'withdraw']
            })
        else:
            gv.UI.set_inv_choice({
                "No piece at that position!":
                lambda x: coords(x) not in valid_squares
            })

        pos = gv.UI.user_input_check_choices(
            "{} ({}), choose a piece to move by "
            "entering its coordinates{}:".format(player, player_type,
                                                 withdraw_string),
            player=player)

        if pos in ['w', 'withdraw']:
            return 'withdraw'

        file_, rank = coords(pos)

        piece = gv.CHESSBOARD[file_][rank]

        valid_moves = valid_moves_one_piece(player_type, file_, rank, piece)

        if not valid_moves:
            gv.prnt("No valid moves for that piece, try again!")

    # Get the player's choice of move
    gv.UI.clear_inv_choices()
    gv.UI.set_inv_choice({
        "Illegal move, choose properly.":
        lambda x: coords(x) not in valid_moves
    })

    move_to = gv.UI.user_input_check_choices('Move to which square?',
                                             player=player)

    file_to, rank_to = coords(move_to)

    # Move the piece and capture any current occupant
    if gv.CHESSBOARD[file_to][rank_to] != ' ':
        captured_piece = gv.CHESSBOARD[file_to][rank_to]
        gv.UI.handle_user_input('{0} captured!'.format(captured_piece),
                                player=player)
        opponents_pieces.remove(captured_piece.lower())
    gv.CHESSBOARD[file_to][rank_to] = piece
    gv.CHESSBOARD[file_][rank] = ' '
    if check_or_mate(player_type):
        gv.prnt('CHECKMATE!')
        return 'checkmate'

    if piece.lower() == 'p':
        promote_pawn(player_type, file_to, rank_to, player)

    # We return False because by this point,
    # withdraw has not been selected.
    return False
コード例 #20
0
def setup_board():
    gv.prnt("Setting up the risk board.")
    gv.prnt("In this version, territories are set up randomly.")
    gv.prnt("In this version, initial army placement is randomised.")
    gv.BOARD = Board()
コード例 #21
0
def choose_pieces(player, n_armies):
    gv.prnt('{0}, choose your pieces!'.format(player))
    gv.prnt('Values of pieces: ')
    gv.prnt('---------------------')
    gv.prnt('Pawn: {0}'.format(gv.CHESSMEN_VALUES['p']))
    gv.prnt('Knight: {0}'.format(gv.CHESSMEN_VALUES['k']))
    gv.prnt('Bishop: {0}'.format(gv.CHESSMEN_VALUES['b']))
    gv.prnt('Rook: {0}'.format(gv.CHESSMEN_VALUES['r']))
    gv.prnt('Queen: {0}'.format(gv.CHESSMEN_VALUES['q']))
    gv.prnt('---------------------')
    gv.prnt('You always start with one kin(g).')
    gv.prnt('Choose from (p)awn, (k)night, (b)ishop, (r)ook, (q)ueen:')

    gv.UI.clear_inv_choices()
    gv.UI.set_inv_choice({
        "Please enter p, k, b, r or q.":
        lambda x: x not in ['p', 'k', 'b', 'r', 'q']
    })
    gv.UI.set_inv_choice({
        "Not enough armies for that piece!":
        lambda x: gv.CHESSMEN_VALUES[x] > n_armies
    })

    pieces = ['g']
    while n_armies > 0:
        pieces.append(
            gv.UI.user_input_check_choices('{0} armies left.'.format(n_armies),
                                           player=player))
        n_armies -= gv.CHESSMEN_VALUES[pieces[-1]]
        gv.prnt("Your forces: {0}".format(pieces))

    return pieces
コード例 #22
0
def print_board(part, clear=False):
    """
    gv.CHESSBOARD[file_][rank]
    ranks are numbers 0-8
    ranks are up-down
    files are letters A-
    files are side-side
    """
    if clear:
        gv.prnt.clear_output()
    if part == 'all':
        prt = (0, 7)
    elif part == 'top':
        prt = (0, 3)
    elif part == 'bottom':
        prt = (4, 7)
    else:
        raise Exception('Unexpected part of the board!')

    for irank in xrange(prt[0], prt[1] + 1):
        if irank % 2:
            colour = ' '
        else:
            colour = '#'
        creamy_filling = {'top': '', 'mid': '', 'bot': ''}
        for ifile_ in xrange(NFILES):
            square = gv.CHESSBOARD[ifile_][irank]
            if colour == '#':
                colour = ' '
            elif colour == ' ':
                colour = '#'
            else:
                raise Exception('Unexpected colour!')
            creamy_filling['top'] += '|{0} {0}'.format(colour)
            creamy_filling['mid'] += '| {1} '.format(colour, square)
            creamy_filling['bot'] += '|{0} {0}'.format(colour)
        gv.prnt(' ' + '+---' * (NFILES) + '+')
        gv.prnt(' ' + creamy_filling['top'] + '|')
        gv.prnt(str(irank) + creamy_filling['mid'] + '|')
        gv.prnt(' ' + creamy_filling['bot'] + '|')
    gv.prnt(' ' + '+---' * (NFILES) + '+')

    files_string = ''
    for ifile_ in xrange(NFILES):
        file_name = chr(97 + ifile_).upper()
        files_string += '  {0} '.format(file_name)
    gv.prnt(' {0} '.format(files_string))
    if gv.AI_PLAYERS_ARE_PLAYING:
        sleep(gv.AI_PRINT_DELAY)
コード例 #23
0
def stalemate(att_pieces, def_pieces):
    if att_pieces == ['g'] and def_pieces == ['g']:
        gv.prnt('STALEMATE!')
        return True
    return False