我正在编写一个神经网络程序来在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
答案 0 :(得分:3)
仍然有太多的代码需要完成,但至少有一件事是可疑的。您通过ConnectFourAIb.py中的ConnectFour模块级调用启动游戏。但是您的_HumanPlayer.get_move
方法再次导入ConnectFourAIb;这将重新触发该文件末尾的两行。
要解决此问题,请使用if __name__ == '__main__'
技巧:
if __name__ == '__main__':
game = ConnectFour()
game.start_new()
这可确保仅在从命令行运行文件时调用这些行,而不是在导入文件时调用这些行。
(顺便说一句,请删除所有那些领先的下划线。他们不添加任何内容,只是让你的代码更难阅读。)