为什么此代码会运行两次?

时间:2017-05-24 09:39:57

标签: python python-2.7 python-import

我正在编写一个神经网络程序来在python中连接四个,并使用现有的minimax算法进行训练。我已经编写了一些基本代码来建立两种算法之间的通信。以下行应导致两个程序之间的一场比赛: - game = ConnectFour() game.start_new() 但是,游戏会播放两次。 (“IA是胜利者”被打印两次。)

我添加了一些调试打印行。有很多代码,但我无法弄清楚问题所在。所以我发布了所有这些内容。我怀疑import语句,但不知道究竟是什么问题。

ConnectFourAIb.py:

from minimax2b import ConnectFour

def get_AI_move(grid):
    i = 0
    while grid[0][i]!=' ':
        i += 1
    return i

game = ConnectFour()
game.start_new()

minimax2b.py:

import os
import random
import time
from abc import ABCMeta, abstractmethod

CONNECT_FOUR_GRID_WIDTH = 7
CONNECT_FOUR_GRID_HEIGHT = 6

CONNECT_FOUR_COLORS = ["x","o"]

class ConnectFour(object):
    _GRID_WIDTH = CONNECT_FOUR_GRID_WIDTH
    _GRID_HEIGHT = CONNECT_FOUR_GRID_HEIGHT
    _grid = None
    _round = None
    _finished = False
    _winner = None
    _current_player = None
    _players = [None, None]
    _COLORS = CONNECT_FOUR_COLORS

    def __init__(self):
        print("__init__")
        self._round = 1
        self._finished = False
        self._winner = None
        self._players[0] = _HumanPlayer(self._COLORS[0])
        self._players[1] = _ComputerPlayer(self._COLORS[1])
        for i in xrange(2):
            print('%s play with %s ' % (self._players[i]._type, self._COLORS[i]))

        self._current_player = self._players[random.randint(0, 1)]
        self._grid = []
        for i in xrange(self._GRID_HEIGHT):
            self._grid.append([])
            for j in xrange(self._GRID_WIDTH):
                self._grid[i].append(' ')

    def start(self):
        print("start")
        while not self._finished:
            self._next_move()

    def start_new(self):
        print("start_new")
        self._round = 1
        self._finished = False
        self._winner = None
        self._current_player = self._players[random.randint(0, 1)]
        self._grid = []
        for i in xrange(self._GRID_HEIGHT):
            self._grid.append([])
            for j in xrange(self._GRID_WIDTH):
                self._grid[i].append(' ')

        self.start()

    def _switch_player(self):
        print("_switch_player")
        if self._current_player == self._players[0]:
            self._current_player = self._players[1]
        else:
            self._current_player = self._players[0]

    def _next_move(self):
        print("_next_move")
        column = self._current_player.get_move(self._grid)
        for i in xrange(self._GRID_HEIGHT - 1, -1, -1):
            if self._grid[i][column] == ' ':
                self._grid[i][column] = self._current_player._color
                self._check_status()
                if self._finished:
                    self._print_state()
                    return 1
                self._switch_player()
                self._round += 1
                return 1

        print("This column is full. Please choose an other column")
        return

    def _check_status(self):
        print("_check_status")
        if self._is_full():
            self._finished = True
        elif self._is_connect_four():
            self._finished = True
            self._winner = self._current_player

    def _is_full(self):
        print("_is_full")
        return self._round > self._GRID_WIDTH * self._GRID_HEIGHT

    def _is_connect_four(self):
        print("_is_connect_four")
        for i in xrange(self._GRID_HEIGHT - 1, -1, -1):
            for j in xrange(self._GRID_WIDTH):
                if self._grid[i][j] != ' ':
                    # check for vertical connect four
                    if self._find_vertical_four(i, j):
                        return True

        return False

    def _find_vertical_four(self, row, col):
        print("_find_vertical_four")
        consecutive_count = 0

        if row + 3 < self._GRID_HEIGHT:
            for i in xrange(4):
                if self._grid[row][col] == self._grid[row + i][col]:
                    consecutive_count += 1
                else:
                    break

            if consecutive_count == 4:
                if self._players[0]._color == self._grid[row][col]:
                    self._winner = self._players[0]
                else:
                    self._winner = self._players[1]
                return True

        return False

    def _print_state(self):
        print("_print_state")
        if self._finished:
            print("Game Over!")
            if self._winner != None:
                print(str(self._winner._type) + " is the winner!")
            else:
                print("Game is a draw")


class _Player(object):
    __metaclass__ = ABCMeta

    _type = None
    _color = None

    def __init__(self, color):
        self._color = color

    @abstractmethod
    def get_move(self, grid):
        pass


class _HumanPlayer(_Player):

    def __init__(self, color):
        super(_HumanPlayer, self).__init__(color)
        self._type = "Human"

    def get_move(self, grid):
        from ConnectFourAIb import get_AI_move
        return get_AI_move(grid)



class _ComputerPlayer(_Player):
    _DIFFICULTY = 5

    def __init__(self, color,_DIFFICULTY=5):
        super(_ComputerPlayer, self).__init__(color)
        self._DIFFICULTY = _DIFFICULTY
        self._type = "IA"

    def get_move(self, grid):
        return 4

1 个答案:

答案 0 :(得分:3)

仍然有太多的代码需要完成,但至少有一件事是可疑的。您通过ConnectFourAIb.py中的ConnectFour模块级调用启动游戏。但是您的_HumanPlayer.get_move方法再次导入ConnectFourAIb;这将重新触发该文件末尾的两行。

要解决此问题,请使用if __name__ == '__main__'技巧:

if __name__ == '__main__':
    game = ConnectFour()
    game.start_new()

这可确保仅在从命令行运行文件时调用这些行,而不是在导入文件时调用这些行。

(顺便说一句,请删除所有那些领先的下划线。他们不添加任何内容,只是让你的代码更难阅读。)