python似乎是自己覆盖变量

时间:2015-02-18 16:23:13

标签: python variables

作为尝试学习python的基础知识,我决定尝试在python 3中重新创建nim stick。我正在使用pyCharm进行此开发。

当AI播放器检查要移除的内容时,lines函数中的game_ai变量似乎无缘无故地覆盖自身。

main.py:

import ai
import helpers

lines = [1, 3, 5, 7]
winner = 0

# String introduction
print('   _____ _   _      _         ')
print('  / ____| | (_)    | |        ')
print(' | (___ | |_ _  ___| | _____  ')
print('  \___ \| __| |/ __| |/ / __| ')
print('  ____) | |_| | (__|   <\__ \ ')
print(' |_____/ \__|_|\___|_|\_\___/ ')
print('The last one to pick up a stick loses!')

# Keep going till we have a winner!
while winner == 0:
    # Redraw the stick board at the start of a turn
    helpers.redraw_sticks(lines)

    # Get user input and remove their sticks
    line = helpers.check_input('Please select a line to remove (a) stick(s) from:', 0, 4, 'line', lines)
    amount = helpers.check_input('Please select how many stick(s) you wish to remove:', 0, 7, 'amount', lines)
    lines = helpers.remove_sticks(lines, line, amount)

    # Check for winner
    winner = helpers.winner_check(lines, 1)

    # Only play the AI if the player doesn't win this go
    if winner == 0:
        # Redraw the board after a go
        helpers.redraw_sticks(lines)

        # Play the AI
        ai_turn = ai.game_ai(lines)
        lines = helpers.remove_sticks(lines, ai_turn[0], ai_turn[1] - 1)

        # Check for winner
        winner = helpers.winner_check(lines, 2)

# Declare the winner!
if winner == 1:
    print('The Human Player wins the game!')
else:
    print('The Computer Player wins the game!')

ai.py:

import helpers
import time


# Our cool kid AI
def game_ai(lines):
    winning_data = [0, 0]
    winning_combo = False

    # Keep going till we get a winning nim sum
    while not winning_combo:
        line = 1

        # Go through every line
        while line <= 4 and not winning_combo:
            # Reset amount value
            amount = 7

            # Make it look like there's actual heavy processing going on here
            print('AI player is thinking...')
            time.sleep(1)

            # Only go if the line actually has sticks
            if lines[line - 1] != 0:
                # Test certain values in a line
                while amount >= 1 and not winning_combo:
                    lines_test = helpers.remove_sticks(lines, line, amount)

                    # If we have a nim sum of 0 we go!
                    if helpers.nim_sum(lines_test) == 0:
                        winning_combo = True
                        winning_data[0] = line
                        winning_data[1] = amount

                        # I'm going to win, I shouldn't do this...
                        if helpers.lines_checksum(lines_test) == 0:
                            winning_data[1] = amount - 1

                    # Increment amount
                    amount -= 1

            # Increment line
            line += 1

    # Return winning data
    return winning_data

helpers.py:

import sys


# Redraws the stick board with updated values
def redraw_sticks(lines):
    # Loop through each line
    for (line, sticks) in enumerate(lines):
        if sticks > 0:
            # Output line number
            sys.stdout.write(str(line + 1) + ': ')

            # And output how many sticks there are
            for x in range(0, sticks):
                sys.stdout.write('|')
            print('')


# Remove sticks on request
def remove_sticks(lines, line, amount):
    # Set line to the correct pointer
    line -= 1

    if lines[line] < amount:
        lines[line] = 0
    else:
        lines[line] = lines[line] - amount

    return lines


# Check if an input is an integer and in the correct range
def check_input(request_message, min_value, max_value, check_type, lines):
    inputting = True
    user_input = 0

    while inputting:
        user_input = input(request_message)

        try:
            # Check if the input is an integer
            user_input = int(user_input)

            # Make sure the input fits in our defined range
            if max_value >= user_input > min_value:
                inputting = False

                # Check if the line has any sticks left
                if check_type == 'line' and lines[user_input - 1] <= 0:
                    print('Error: Line is already empty')
                    inputting = True

            else:
                print('Error: Invalid range value entered')
        except ValueError:
            print('Error: String input entered')

    # Return the input after checks
    return user_input


def nim_sum(lines):
    # First we need to calculate the multiples
    nim_sum_total = 0

    for (pointer, sticks) in enumerate(lines):
        # Calculate multiples of 4
        nim_sum_total += sticks // 4
        sticks %= 4

        # Calculate multiples of 2
        nim_sum_total += sticks // 2
        sticks %= 2

        # Calculate multiples of 1
        nim_sum_total += sticks // 1

    return nim_sum_total % 2


# Check how many sticks are left
def lines_checksum(lines):
    checksum = 0

    # Calculate remaining sticks
    for sticks in lines:
        checksum += sticks

    return checksum


# Check if a winner has been found
def winner_check(lines, player):
    checksum = lines_checksum(lines)

    # Return if we have a winner
    if checksum == 1:
        return player
    else:
        return 0

1 个答案:

答案 0 :(得分:0)

Python中的所有内容都通过引用传递,因此game_ai中的lines变量引用与主程序中lines变量相同的列表。因此,当您从中移除棒时,最终会清除共享线变量。

要解决此问题,您可以先将game_ai中的行复制为lines = lines.copy()