I have a problem with an algorithmic task. There is content of it: "You have ten points on a plane and none three of them are collinear, each pair of different points is connected by line segment, which is green or blue. Calculate how many triangles have sides only in one colour." I tried a solution with n-ary trees but I get repeated triangles with cyclic permutations of integers on the result list.
Patryk, the problem is solvable with n-trees. However, to avoid cyclic permutations you need to skip symmetric line segments. If you create a line segment from 0 -> 1 you do not need to create a segment from 1 -> 0. Below is a complete code which solves the problem with n-trees with the recursive depth-first search. Excuse for Polish names of classes and methods. The interface is in English however. If you analyze the code you will get the point surely.
from random import choice
import copy
class Punkt:
def __init__(self, numer):
self.__numer = numer
self.__odcinki = {}
def dodaj_odcinek_wychodzący(self, punkt_docelowy, kolor):
self.__odcinki[punkt_docelowy] = Odcinek(self.__numer, punkt_docelowy, kolor)
def wez_odcinek_do_punktu_docelowego(self, punkt_docelowy):
return (punkt_docelowy, self.__odcinki[punkt_docelowy].wez_kolor())
def liczba_odcinkow(self):
return len(self.__odcinki)
def wez_kolor_punktu_docelowego(self, punkt_docelowy):
return self.__odcinki[punkt_docelowy].wez_kolor()
def lista_punktow_docelowych(self):
return self.__odcinki.keys()
class Odcinek:
def __init__(self, punkt_zrodlowy, punkt_docelowy, kolor):
self.__punkt_zrodlowy = punkt_zrodlowy
self.__punkt_docelowy = punkt_docelowy
self.__kolor = kolor
def wez_kolor(self):
return self.__kolor
class Structure:
def __init__(self, liczba_punktow=10):
self.__punkty = [Punkt(i)
for i in range(liczba_punktow)]
for i in range(liczba_punktow):
for j in range(i + 1, liczba_punktow):
self.__punkty[i].dodaj_odcinek_wychodzący(j, choice(["green", "blue"]))
# for j in range(liczba_punktow):
# for i in range (j + 1, liczba_punktow):
# self.__punkty[j].dodaj_odcinek_wychodzący(*(self.__punkty[j].wez_odcinek_do_punktu_docelowego(i)))
def wez_punkt(self, numer):
return self.__punkty[numer]
def wez_liczbe_punktow(self):
return len(self.__punkty)
class Search:
def __init__(self, struktura):
self.__s = struktura
def wez_liczbe_punktow(self):
return self.__s.wez_liczbe_punktow()
def wez_punkt(self, numer):
return self.__s.wez_punkt(numer)
def szukaj(self, kolor="green"):
self.__szukany_kolor = kolor
lista_trojkatow = []
liczba_trojkatow = 0
wszystkie_trojkaty = []
for i in range(self.wez_liczbe_punktow()):
lista_odwiedzonych_punktow = [i]
lista_trojkatow = self.szukaj_z_punktu(i,lista_odwiedzonych_punktow,lista_trojkatow)
return len(lista_trojkatow), lista_trojkatow
def wez_szukany_kolor(self):
return self.__szukany_kolor
def szukaj_z_punktu(self, numer, trojkat, lista_trojkatow):
if len(trojkat) == 3: # jeżeli zebraliśmy już trzy punkty to brakuje tylko zamykającego, czwartego
if self.wez_punkt(trojkat[0]).wez_kolor_punktu_docelowego(
trojkat[-1]) == self.wez_szukany_kolor(): # sprawdź czy do punktu zamykającego prowadzi odcinek o szukanym kolorze
trojkat.append(trojkat[0]) # dodaj punkt zamykajacy do trójkąta
lista_trojkatow.append(trojkat) # dodaj trojkąt do listy trójkątów
# return lista_trojkatow # zwróć liste trójkątów obliczonych dotychczas
else:
potomkowie = []
for punkt_docelowy in self.wez_punkt(numer).lista_punktow_docelowych():
if self.wez_punkt(numer).wez_kolor_punktu_docelowego(punkt_docelowy) == self.wez_szukany_kolor():
potomkowie.append(punkt_docelowy)
for potomek in potomkowie:
trojkat_kopia = copy.copy(trojkat)
trojkat_kopia.append(potomek)
lista_trojkatow = self.szukaj_z_punktu(potomek, trojkat_kopia, lista_trojkatow)
return lista_trojkatow
if __name__ == "__main__":
s = Structure()
for source_point in range(s.wez_liczbe_punktow()):
for destination_point in s.wez_punkt(source_point).lista_punktow_docelowych():
print(f"{source_point} -> {destination_point} = {s.wez_punkt(source_point).wez_kolor_punktu_docelowego(destination_point)}")
color = "green"
searching = Search(s)
number_of_triangles, all_triangles = searching.szukaj("green")
print(f"Number of triangles of color {color} = {number_of_triangles}")
print(f"List of all triangles: {all_triangles}")
I am writing an application in python with urwid.
I need an Edit widget with autocompletion. Haven't seen one in the documentation so I have tried implementing it on my own based on the pop_up example.
However, I am faced with the fact that the pop_up widget has the focus which is a problem because:
The cursor in the edit widget is not visible. When using the left and right arrow keys without counting how often you have pressed them you do not know where the next character will be inserted.
All user input goes to the pop_up widget and not to the PopUpLauncher, although most of the key events are meant for the edit widget. I cannot call Edit.keypress because I don't know the size of the edit widget. Therefore I need to duplicate code from urwid.
How can I set the PopUpLauncher to have the focus?
From there on this answer might be helpful.
A strongly simplified version of my custom widget class:
#!/usr/bin/env python
import urwid
class AutoCompleteEdit(urwid.PopUpLauncher):
CMD_INSERT_SELECTED = "complete"
command_map = urwid.CommandMap()
command_map['tab'] = CMD_INSERT_SELECTED
def __init__(self, get_completions):
self.edit_widget = urwid.Edit()
self.__super.__init__(self.edit_widget)
self.get_completions = get_completions
# ------- user input ------
def keypress(self, size, key):
cmd = self.command_map[key]
if cmd is None:
out = self.__super.keypress(size, key)
self.update_completions()
return out
return self.__super.keypress(size, key)
def forwarded_keypress(self, key):
if self.edit_widget.valid_char(key):
#if (isinstance(key, text_type) and not isinstance(self._caption, text_type)):
# # screen is sending us unicode input, must be using utf-8
# # encoding because that's all we support, so convert it
# # to bytes to match our caption's type
# key = key.encode('utf-8')
self.edit_widget.insert_text(key)
self.update_completions()
return
cmd = self.command_map[key]
if cmd == self.CMD_INSERT_SELECTED:
self.insert_selected()
return
elif cmd == urwid.CURSOR_LEFT:
p = self.edit_widget.edit_pos
if p == 0:
return key
p = urwid.move_prev_char(self.edit_widget.edit_text, 0, p)
self.edit_widget.set_edit_pos(p)
elif cmd == urwid.CURSOR_RIGHT:
p = self.edit_widget.edit_pos
if p >= len(self.edit_widget.edit_text):
return key
p = urwid.move_next_char(self.edit_widget.edit_text, p, len(self.edit_widget.edit_text))
self.edit_widget.set_edit_pos(p)
elif key == "backspace":
self.edit_widget.pref_col_maxcol = None, None
if not self.edit_widget._delete_highlighted():
p = self.edit_widget.edit_pos
if p == 0:
return key
p = urwid.move_prev_char(self.edit_widget.edit_text,0,p)
self.edit_widget.set_edit_text(self.edit_widget.edit_text[:p] + self.edit_widget.edit_text[self.edit_widget.edit_pos:])
self.edit_widget.set_edit_pos(p)
elif key == "delete":
self.edit_widget.pref_col_maxcol = None, None
if not self.edit_widget._delete_highlighted():
p = self.edit_widget.edit_pos
if p >= len(self.edit_widget.edit_text):
return key
p = urwid.move_next_char(self.edit_widget.edit_text,p,len(self.edit_widget.edit_text))
self.edit_widget.set_edit_text(self.edit_widget.edit_text[:self.edit_widget.edit_pos] + self.edit_widget.edit_text[p:])
else:
return key
self.update_completions()
return key
def update_completions(self):
i = self.edit_widget.edit_pos
text = self.edit_widget.edit_text[:i]
prefix, completions = self.get_completions(text)
self.prefix = prefix
self.completions = completions
if not self.completions:
if self.is_open():
self.close_pop_up()
return
if not self.is_open():
self.open_pop_up()
self._pop_up_widget.update_completions(completions)
def insert_selected(self):
text = self._pop_up_widget.get_selected()
i = self.edit_widget.edit_pos - len(self.prefix)
assert i >= 0
text = text[i:]
self.edit_widget.insert_text(text)
self.close_pop_up()
# ------- internal ------
def is_open(self):
return self._pop_up_widget
# ------- implementation of abstract methods ------
def create_pop_up(self):
return PopUpList(self.forwarded_keypress)
def get_pop_up_parameters(self):
height = len(self.completions)
width = max(len(x) for x in self.completions)
return {'left':len(self.prefix), 'top':1, 'overlay_width':width, 'overlay_height':height}
class PopUpList(urwid.WidgetWrap):
ATTR = 'popup-button'
ATTR_FOCUS = 'popup-button-focus'
def __init__(self, keypress_callback):
self.body = urwid.SimpleListWalker([urwid.Text("")])
widget = urwid.ListBox(self.body)
widget = urwid.AttrMap(widget, self.ATTR)
self.__super.__init__(widget)
self.keypress_callback = keypress_callback
def update_completions(self, completions):
self.body.clear()
for x in completions:
widget = ListEntry(x)
widget = urwid.AttrMap(widget, self.ATTR, self.ATTR_FOCUS)
self.body.append(widget)
def get_selected(self):
focus_widget, focus_pos = self.body.get_focus()
return self.body[focus_pos].original_widget.text
def keypress(self, size, key):
key = self.keypress_callback(key)
if key:
return super().keypress(size, key)
class ListEntry(urwid.Text):
#https://stackoverflow.com/a/56759094
_selectable = True
signals = ["click"]
def keypress(self, size, key):
"""
Send 'click' signal on 'activate' command.
"""
if self._command_map[key] != urwid.ACTIVATE:
return key
self._emit('click')
def mouse_event(self, size, event, button, x, y, focus):
"""
Send 'click' signal on button 1 press.
"""
if button != 1 or not urwid.util.is_mouse_press(event):
return False
self._emit('click')
return True
if __name__ == '__main__':
palette = [
('popup-button', 'white', 'dark blue'),
('popup-button-focus', 'white,standout', 'dark blue'),
('error', 'dark red', 'default'),
]
completions = ["hello", "hi", "world", "earth", "universe"]
def get_completions(start):
i = start.rfind(" ")
if i == -1:
prefix = ""
else:
i += 1
prefix = start[:i]
start = start[i:]
return prefix, [word for word in completions if word.startswith(start)]
widget = AutoCompleteEdit(get_completions)
widget = urwid.Filler(widget)
#WARNING: note the pop_ups=True
urwid.MainLoop(widget, palette, pop_ups=True).run()
I have found a solution for the first part of the problem at least (visibility of the cursor): overriding the render method in the AutoCompleteEdit class:
def render(self, size, focus=False):
if self.is_open():
focus = True
return self.__super.render(size, focus)
The second problem, code duplication, still remains.
Actually it's more than just code duplication because some functionality (moving the cursor to the very beginning or the very end) is using the size argument of the keypress method. I don't know the size so I can't just copy it out of there.
So if someone knows a better way I would be grateful.
I'm trying to create two subclasses based on the same parent class, so that they each have their own versions of the same variables defined in the parent object. However I realized that changing these variables in one of these subclasses will cause the versions in the other subclass to change as well. I know I am probably not fully understanding the idea of Inheritance. Please help!
import random
class PlayerParent():
id = 1
# Cooperate: True; Betrayal: False
opponent_moves_history = {}
self_moves_history = {}
def append_opponent_history(self, round_num, c_true, misunderstand=0.0):
# randomly change the result based on probability given in misunderstand
random_num = random.uniform(0, 1)
if random_num <= misunderstand:
c_true = not c_true
self.opponent_moves_history[round_num] = c_true
def append_self_history(self, round_num, c_true, misunderstand=0.0):
# randomly change the result based on probability given in misunderstand
random_num = random.uniform(0, 1)
if random_num <= misunderstand:
c_true = not c_true
self.self_moves_history[round_num] = c_true
score = int(0)
def score_keeper(self, round_num):
if (self.opponent_moves_history[round_num] == True) and (self.self_moves_history[round_num] == False):
self.score += 7
if (self.opponent_moves_history[round_num] == True) and (self.self_moves_history[round_num] == True):
self.score += 5
if (self.opponent_moves_history[round_num] == False) and (self.self_moves_history[round_num] == True):
self.score += 1
if (self.opponent_moves_history[round_num] == False) and (self.self_moves_history[round_num] == False):
self.score += 2
def get_score(self):
return self.score
class TitForTat(PlayerParent):
def rule(self, round_num):
if len(self.opponent_moves_history) == 0:
return True
else:
return self.opponent_moves_history[round_num - 1]
class Random(PlayerParent):
def rule(self, round_num):
random_num = random.uniform(0, 1)
if random_num >= 0.5:
return True
else:
return False
Random = Random()
Random.id = 1
TitForTat = TitForTat()
TitForTat.id = 2
def match(a, b):
game_counter = 1
# while game_counter <= 10:
#a_result = a.rule(game_counter)
# b_result = b.rule(game_counter)
# print(a_result, b_result)
# a.append_self_history(game_counter, a_result)
# b.append_opponent_history(game_counter, a_result)
# b.append_self_history(game_counter, b_result)
# a.append_opponent_history(game_counter, b_result)
# a.score_keeper(game_counter)
# b.score_keeper(game_counter)
# game_counter += 1
# print(a.get_score(), b.get_score())
a.self_moves_history[1] = True
print(a.self_moves_history, '\n', b.self_moves_history)
match(Random, TitForTat)
Resulting a.self_moves_history and b.self_moves_history is identical even though no alteration has been done to the b class variable.
I commented out chunks of the codes just to test where went wrong.
You are making opponent_moves_history a class variable, so naturally any change to it is class-wide.
In your case you should make opponent_moves_history, along with self_moves_history and id instance variables instead, so that changes made to them are specific to the instances.
class PlayerParent():
def __init__(self):
self.id = 1
self.opponent_moves_history = {}
self.self_moves_history = {}
I am trying to create a BFS solution to the 8 puzzle problem in python. However after I 'get()' a node from the queue and find the puzzle state inside that node it seems the puzzle object has turned into a list object without the method 'getMoves()'. I am wondering why it is not still a Puzzle object?
import collections
import queue
class Node:
def __init__(self, Puzzle, last=None):
self.puzzle = Puzzle
self.last = last
def getPuzzle(self):
return self.puzzle
def getLast(self):
return self.last
class Puzzle:
def __init__(self, startState, goalState):
self.state = startState
self.goal = goalState
def getState():
return self.state
def getMoves(self):
currentState = self.state
possibleNewStates = []
zeroPos = currentState.index(0)
if zeroPos == 0:
possibleNewStates.append(move(0,1))
possibleNewStates.append(move(0,3))
elif zeroPos == 1:
possibleNewStates.append(move(1,0))
possibleNewStates.append(move(1,2))
possibleNewStates.append(move(1,4))
elif zeroPos == 2:
possibleNewStates.append(move(2,1))
possibleNewStates.append(move(2,5))
elif zeroPos == 3:
possibleNewStates.append(move(3,0))
possibleNewStates.append(move(3,4))
possibleNewStates.append(move(3,6))
elif zeroPos == 4:
possibleNewStates.append(self.move(4,1))
possibleNewStates.append(self.move(4,3))
possibleNewStates.append(self.move(4,5))
possibleNewStates.append(self.move(4,7))
elif zeroPos == 5:
possibleNewStates.append(move(5,2))
possibleNewStates.append(move(5,4))
possibleNewStates.append(move(5,8))
elif zeroPos == 6:
possibleNewStates.append(move(6,3))
possibleNewStates.append(move(6,7))
elif zeroPos == 7:
possibleNewStates.append(move(7,4))
possibleNewStates.append(move(7,6))
possibleNewStates.append(move(7,8))
else:
possibleNewStates.append(move(8,5))
possibleNewStates.append(move(8,7))
return possibleNewStates
def move(self, current, to):
changeState = self.state
save = changeState[to]
changeState[to] = changeState[current]
changeState[current] = save
return changeState
def printPuzzle(self):
copyState = self.state
print(copyState)
'''
for i in range(9):
if i == 2 or i == 5:
print((str)(copyState[i]))
else:
print((str)(copyState[i])+" ", end="")
print()
'''
def isSolved(self):
return self.state == self.goal
class Solver:
def __init__(self, Puzzle):
self.puzzle = Puzzle
def solveBFS(self):
puzzle = self.puzzle
startNode = Node(puzzle)
myQueue = queue.Queue(0)
myQueue.put(startNode)
myPuzzle = startNode.getPuzzle()
print(myPuzzle.isSolved())
while myQueue:
currentNode = myQueue.get()
currentPuzzle = currentNode.puzzle
if currentPuzzle == [0,1,2,3,4,5,6,7,8]:
return currentNode
nextMoves = currentPuzzle.getMoves() # << ERROR HERE
for state in nextMoves:
nextNode = Node(state, currentNode)
myQueue.put(nextNode)
startingState = [7,2,4,5,0,6,8,3,1]
goalState = [0,1,2,3,4,5,6,7,8]
myPuzzle = Puzzle(startingState, goalState)
mySolver = Solver(myPuzzle)
goalNode = mySolver.solveBFS()
goalPuzzle = goalNode.getPuzzle()
goalPuzzle.printPuzzle()
That's because in some cases, state must be a list when you create a new node:
nextMoves = currentPuzzle.getMoves()
for state in nextMoves:
nextNode = Node(state, currentNode)
Here state must've been a list returned from the Puzzle.getMoves() list:
def getMoves(self):
# ...
possibleNewStates = []
# append various objects to possibleNewStates.
return possibleNewStates
In getMoves() you use two callables to produces new states:
possibleNewStates.append(move(0,1))
and
possibleNewStates.append(self.move(4,1))
Puzzle.move() produces a list; you do some swapping on self.state which you set to a list:
def move(self, current, to):
changeState = self.state
save = changeState[to]
changeState[to] = changeState[current]
changeState[current] = save
return changeState
Note that this mutates self.state in-place; you did not create a copy of the value here.
self.state was set from the first argument to Puzzle(), which was a list:
startingState = [7,2,4,5,0,6,8,3,1]
goalState = [0,1,2,3,4,5,6,7,8]
myPuzzle = Puzzle(startingState, goalState)
so self.move() returns a list, not a Puzzle() instance.
You didn't share the definition of the move() global function; if this also produces a list then that's another cause of your Node.puzzle values becoming lists.
You probably want to correct all move() calls to use self.move(), and for self.move() to return a new Puzzle() instance. You'll need to create a copy of self.state list here too:
def move(self, current, to):
changeState = self.state[:] # create a copy
changeState[to], changeState[current] = changeState[current], changeState[to]
return Puzzle(changeState, self.goal)
All move() in getMoves() should be changed to self.move(). Otherwise you are working with an unbound Puzzle.
So I am designing a battleship backend system that will be running on google apps engine... I just started yesterday and designed a framework for the game.
Unfortunately for me, I have not coded too much in python so I am not too familiar with the specifics of the language. I keep getting the following error when I try to run the program:
File "C:\Users\Shlomo\Desktop\eclipse\plugins\org.python.pydev_2.7.5.2013052819\pysrc\pydev_runfiles.py", line 432, in __get_module_from_str
mod = __import__(modname)
File "C:\Users\Shlomo\workspace\battleship\Battleship.py", line 222, in <module>
battleship = BattleshipGame("Shlomo",1,1,4,1,1,2,5,2,1,3,3,3,1,4,2,4,1,5,5,5,"John",1,1,4,1,1,2,5,2,1,3,3,3,1,4,2,4,1,5,5,5)
File "C:\Users\Shlomo\workspace\battleship\Battleship.py", line 210, in __init__
field = self.player1_field.getField()
AttributeError: 'NoneType' object has no attribute 'getField'
ERROR: Module: Battleship could not be imported (file: C:\Users\Shlomo\workspace\battleship\Battleship.py).
So I translated this error as the variable field is not getting initialized with the PlayerField object...
Here is my code:
import random
class Player:
player_name = None
player_id = None
game_id = None
your_turn = False
player_field = None
hit_field = None
opponent = None
def __init__(self,name,player_field,hit_field,opponent):
self.player_name = name
self.player_field = player_field
self.hit_field = hit_field
self.opponent = opponent
def getPlayerField(self):
return self.player_field
def performHit(self,x,y):
mark = None
hit = self.opponent.getPlayerField.hitAt(x,y)
if hit:
mark = 'X'
else:
mark = 'O'
self.hit_field.markHitField(x,y,mark)
class HitField:
hit_field = None
def __init__(self):
hit_field = [[0 for i in xrange(10)] for i in xrange(10)]
def markHitField(self,x,y,mark):
self.hitfield[x][y] = mark
class PlayerField:
player_field = [[0 for i in xrange(10)] for i in xrange(10)]
shipsOnField = []
goodToGo = False
def __init__(self,battleship,aircraft,destroyer,submarine,patrol):
if self.validPlacement(battleship)and self.validPlacement(aircraft)and self.validPlacement(destroyer) and self.validPlacement(submarine) and self.validPlacement(patrol):
self.placeShip(battleship)
self.placeShip(aircraft)
self.placeShip(destroyer)
self.placeShip(submarine)
self.placeShip(patrol)
self.shipsOnField.append(battleship)
self.shipsOnField.append(aircraft)
self.shipsOnField.append(destroyer)
self.shipsOnField.append(submarine)
self.shipsOnField.append(patrol)
self.goodToGo = True
else:
print "some pieces have been placed incorrectly"
def validPlacement(self,ship):
hx = ship.getHeadX;
hy = ship.getHeadY;
tx = ship.getTailX;
ty = ship.getTailY;
if not hx > 0 and not hx < 11:
return False
return True
def placeShip(self,ship):
hx = ship.getHeadX();
hy = ship.getHeadY();
tx = ship.getTailX();
ty = ship.getTailY();
for y in range(ty,hy):
for x in range(tx,hx):
self.player_field[x][y] = ship.getShipID
def hitAt(self,x,y):
hitPos = self.player_field[x][y]
if not hitPos == 0 and not hitPos == 'X':
self.getShipByID(hitPos).removeHealth
self.player_field[x][y] = 'X'
return True
def getShipByID(self,ID):
for ship in self.shipsOnField:
if ship.getShipID == ID:
return ship
def getField(self):
return self.player_field
class Ship(object):
ship_id = None
ship_name = None
max_health = None
remaining_health = None
head_pos_x = None
head_pos_y = None
tail_pos_x = None
tail_pos_y = None
def __init__(self,id,name,max,hx,hy,tx,ty):
self.ship_id = id
self.max_health = max
self.remaining_health = max
self.ship_name = name
self.head_pos_x = hx
self.head_pos_y = hy
self.tail_pos_x = tx
self.tail_pos_y = ty
self.remaining_health = max
def removeHealth(self):
self.remaining_health -= 1
def getHeadX(self):
return self.head_pos_x
def getHeadY(self):
return self.head_pos_y
def getTailX(self):
return self.tail_pos_x
def getTailY(self):
return self.tail_pos_y
def getRemainingHealth(self):
return self.remaining_health
def getShipID(self):
return self.ship_id
class Battleship(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,1,"Battle Ship",4,hx,hy,tx,ty)
class AircraftCarrier(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,2,"Aircraft Carrier",5,hx,hy,tx,ty)
class Destroyer(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,3,"Destroyer",3,hx,hy,tx,ty)
class Submarine(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,4,"Submarine",3,hx,hy,tx,ty)
class PatrolBoat(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,5,"Patrol Boat",2,hx,hy,tx,ty)
class BattleshipGame:
current_turn = None
player1 = None
player2 = None
player1_field = None
player1_opponent = player2
player2_field = None
player2_opponent = player1
def firstTurn(self):
rand = random.randint(1,2)
if rand==1:
return self.player1
else:
return self.player2
def printGameBoard(self):
field = self.player1_field.getField()
for y in range(1,10):
for x in range(1,10):
print field[x][y]
print '\n'
def __init__(self,p1name,p1bshx,p1bshy,p1bstx,p1bsty
,p1dhx,p1dhy,p1dtx,p1dty
,p1shx,p1shy,p1stx,p1sty
,p1pbhx,p1pbhy,p1pbtx,p1pbty
,p1achx,p1achy,p1actx,p1acty
,p2name,p2bshx,p2bshy,p2bstx,p2bsty
,p2dhx,p2dhy,p2dtx,p2dty
,p2shx,p2shy,p2stx,p2sty
,p2pbhx,p2pbhy,p2pbtx,p2pbty
,p2achx,p2achy,p2actx,p2acty):
player1_field = PlayerField(Battleship(p1bshx,p1bshy,p1bstx,p1bsty),
AircraftCarrier(p1achx,p1achy,p1actx,p1acty),
Destroyer(p1dhx,p1dhy,p1dtx,p1dty),
Submarine(p1shx,p1shy,p1stx,p1sty),
PatrolBoat(p1pbhx,p1pbhy,p1pbtx,p1pbty))
player2_field = PlayerField(Battleship(p2bshx,p2bshy,p2bstx,p2bsty),
AircraftCarrier(p2achx,p2achy,p2actx,p2acty),
Destroyer(p2dhx,p2dhy,p2dtx,p2dty),
Submarine(p2shx,p2shy,p2stx,p2sty),
PatrolBoat(p2pbhx,p2pbhy,p2pbtx,p2pbty))
player1 = Player(p1name,self.player1_field,HitField(),self.player2)
player2 = Player(p2name,self.player2_field,HitField(),self.player1)
self.current_turn = self.firstTurn()
battleship = BattleshipGame("Player1",1,1,4,1,1,2,5,2,1,3,3,3,1,4,2,4,1,5,5,5,"Player2",1,1,4,1,1,2,5,2,1,3,3,3,1,4,2,4,1,5,5,5)
battleship.printGameBoard()
Sorry about the sytax, I had trouble pasting it in the code format. This code probably has a few problems but I have not been able to get passed this problem yet...
What am I doing wrong?
In your __init__, you're assigning to a local variable player1_field rather than to instance data. Instead of:
player1_field = PlayerField(...
You want:
self.player1_field = PlayerField(...
Without that, you're trying to deference your class's value for player1_field, which is None.
Python isn't Java or whatever language you are trying to write. These mutable class attributes are unlikely to do what you think they do.
class PlayerField:
player_field = [[0 for i in xrange(10)] for i in xrange(10)]
shipsOnField = []
goodToGo = False