# Advanced game of Tic Tac Toe
# Author: Bob
# Version: TypeError
#******************************
#import modules
import random
import mcommandline
#******************************



class Human(object):
    def __init__(self):
        self.hposition = 0
        self.hmove = ["X", self.hposition]
        self.question = ""
    def makemove(self):
        self.hmove[1] = input("1-9: ")
    def question():
        question = input("Yes/No: ").lower()

class Board(object,Human()):
    def __init__(self):
        self.board = []
        self.mark = []
    def makeboard(self):
        for i in range(9):
            self.mark.append(i)
        self.board.append((("["+str(self.mark[0])+"]"),("["+str(self.mark[1])+"]"),("["+str(self.mark[2])+"]")))
        self.board.append((("["+str(self.mark[3])+"]"),("["+str(self.mark[4])+"]"),("["+str(self.mark[5])+"]")))
        self.board.append((("["+str(self.mark[6])+"]"),("["+str(self.mark[7])+"]"),("["+str(self.mark[8])+"]")))
    def printboard(self):
        print(self.board[0][0],self.board[0][1],self.board[0][2])
        print(self.board[1][0],self.board[1][1],self.board[1][2])
        print(self.board[2][0],self.board[2][1],self.board[2][2])
    def addmove(self):
        self.mark[int(self.hmove[0])].pop
        self.mark[int(self.hmove[0])].append(self.hmove[1])
    def checkwin():
        pass

#startup
Board = Board()
Board.makeboard()
Board.printboard()
Human = Human()

def Round():
    Human.makemove()
    Board.addmove()
    Board.printboard()
Round()              

I wanted to get the hang of class inheritance, with the most original idea ever I embarked on this quest...
So.. I have an error:
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
-I do not know what this means.
-More precisely I do not know what metaclasses mean
-You may comment on my dreadful make board function lol
-Could I have a fix for this I guess this is just going to be a small snippet of code that needs fixing rather than the whole program, I prefer learning by examples along with an explantion of what I did wrong if you would be kind to do so please :)

Many Thanks!

Edited 4 Years Ago by ThePythonNoob

Note how the class Board is declared inheriting Human. Also, the init in Board overrides the init in Human so you have to explicitly call it with "super" in new style classes, otherwise the variables in Human's init are not declared.

class Board(Human):
    def __init__(self):
        super(Board,self).__init__()
        self.board = []
        self.mark = []

The statement Human=Human() does nothing. Also, you will not be able to have more than once instance of the Board class with this code. You have redefined it to be an instance instead since the instance and the class have the same name.

def Round(Board):
    Board.makemove()
    Board.addmove()
    Board.printboard()

#startup
Board = Board()   ## Board is no longer a class
Board.makeboard()
Board.printboard()
##Human = Human()

Round(Board)              

## this won't work as "Board" no longer points to a class.
board_2= Board()  

Edited 4 Years Ago by woooee

Thanks for the reply, I managed to fix that but now I have a problem getting some variables in the right scope.

# Advanced game of Tic Tac Toe
# Author: Bob
# Version: TypeError
#******************************
#import modules
import random
import mcommandline
#******************************



class Human(object):
    def __init__(self):
        self.hmove = ["X", 1]
        self.question = ""
    def makemove(self):
        self.hmove[1] = input("1-9: ")
        int(self.hmove[1])
        return self.hmove
    def question():
        question = input("Yes/No: ").lower()

class Board(Human):
    def __init__(self):
        super(Board,self).__init__()
        self.board = []
        self.mark = []
    def makeboard(self):
        for i in range(9):
            self.mark.append(i+1)
        self.board.append((("["+str(self.mark[0])+"]"),("["+str(self.mark[1])+"]"),("["+str(self.mark[2])+"]")))
        self.board.append((("["+str(self.mark[3])+"]"),("["+str(self.mark[4])+"]"),("["+str(self.mark[5])+"]")))
        self.board.append((("["+str(self.mark[6])+"]"),("["+str(self.mark[7])+"]"),("["+str(self.mark[8])+"]")))
    def updateboard(self):
        self.board = []
        self.board.append((("["+str(self.mark[0])+"]"),("["+str(self.mark[1])+"]"),("["+str(self.mark[2])+"]")))
        self.board.append((("["+str(self.mark[3])+"]"),("["+str(self.mark[4])+"]"),("["+str(self.mark[5])+"]")))
        self.board.append((("["+str(self.mark[6])+"]"),("["+str(self.mark[7])+"]"),("["+str(self.mark[8])+"]")))
    def printboard(self):
        print(self.board[0][0],self.board[0][1],self.board[0][2])
        print(self.board[1][0],self.board[1][1],self.board[1][2])
        print(self.board[2][0],self.board[2][1],self.board[2][2])
    def addmove(self):
        self.mark[int(self.hmove[1])-1]=self.hmove[0]
    def checkwin():
        pass

#startup
B = Board()
B.makeboard()
B.printboard()
H = Human()

def Round():
    H.makemove()
    B.addmove()
    B.updateboard()
    B.printboard()
Round()     

self.hmove[1] is not being updated in the board class when I assign a value to it from an input in the human class. Could someone help, Thanks :)

I guess I could use super(Board,self).makemove() in the addmove function but this would eliminate my structuring of the code and would complicate using the board class with the human and computer class together which I plan to do.

Human.makemove is different from Board.makemove (different "name space"). Read the last part of my first reply again. Also, you can replace

        self.board.append((("["+str(self.mark[0])+"]"),("["+str(self.mark[1])+"]"),("["+str(self.mark[2])+"]")))
        self.board.append((("["+str(self.mark[3])+"]"),("["+str(self.mark[4])+"]"),("["+str(self.mark[5])+"]")))
        self.board.append((("["+str(self.mark[6])+"]"),("["+str(self.mark[7])+"]"),("["+str(self.mark[8])+"]")))
    def updateboard(self):
        self.board = []
        self.board.append((("["+str(self.mark[0])+"]"),("["+str(self.mark[1])+"]"),("["+str(self.mark[2])+"]")))
        self.board.append((("["+str(self.mark[3])+"]"),("["+str(self.mark[4])+"]"),("["+str(self.mark[5])+"]")))
        self.board.append((("["+str(self.mark[6])+"]"),("["+str(self.mark[7])+"]"),("["+str(self.mark[8])+"]")))

with

for ctr in range(0, 9):
    self.board.append("[%d]" % (self.mark[ctr]))

Edited 4 Years Ago by woooee

Im having trouble.... Im get an index error

# Advanced game of Tic Tac Toe
# Author: Bob
# Version: TypeError
#******************************
#import modules
import random
import mcommandline
#******************************
try:
    print("Boot:")
except SyntaxError:
    raise SyntaxError("Update to Python 3.2 to play!")


class Human(object):
    def __init__(self):
        self.hmove = ["X", 1]
        self.question = ""
    def makemove(self):
        self.hmove[1] = input("1-9: ")
        int(self.hmove[1])
    def question():
        question = input("Yes/No: ").lower()

class Board(Human):
    def __init__(self):
        super(Board,self).__init__()
        self.board = []
        self.mark = []
    def makeboard(self):
        for i in range(9):
            self.mark.append(i+1)
        self.board.append((("["+str(self.mark[0])+"]"),("["+str(self.mark[1])+"]"),("["+str(self.mark[2])+"]")))
        self.board.append((("["+str(self.mark[3])+"]"),("["+str(self.mark[4])+"]"),("["+str(self.mark[5])+"]")))
        self.board.append((("["+str(self.mark[6])+"]"),("["+str(self.mark[7])+"]"),("["+str(self.mark[8])+"]")))
    def updateboard(self):
        self.board = []
        self.board.append((("["+str(self.mark[0])+"]"),("["+str(self.mark[1])+"]"),("["+str(self.mark[2])+"]")))
        self.board.append((("["+str(self.mark[3])+"]"),("["+str(self.mark[4])+"]"),("["+str(self.mark[5])+"]")))
        self.board.append((("["+str(self.mark[6])+"]"),("["+str(self.mark[7])+"]"),("["+str(self.mark[8])+"]")))
    def printboard(self):
        print(self.board[0][0],self.board[0][1],self.board[0][2])
        print(self.board[1][0],self.board[1][1],self.board[1][2])
        print(self.board[2][0],self.board[2][1],self.board[2][2])
    def addmove(self):
        print(str(self.hmove[1]))
        self.mark[int(self.hmove[1])-1]=self.hmove[0]
    def checkwin():
        pass

#startup
B = Board()
B.makeboard()
B.printboard()
H = Human()

def Round(Board,Human):
    Human().makemove()
    Board().addmove()
    Board().updateboard()
    Board().printboard()
Round(Board,Human)              

I think that you're having some conceptual issues with inheritance, resulting in what is sometimes called 'spaghetti inheritance' (that is, inheriting from an otherwise unrelated class just to get a desired behavior). There's a simple test to see if the inheritance is valid: is a Board a specific example of a Human in your model? If it isn't then Board shouldn't be inheriting from Human.

Perhaps a change of names will clarify things a bit. Replace Human with the more general name Player, and subclass Player with HumanPlayer and AiPlayer. Separate the playing behaviors of Board out into AiPlayer, and have Board be a representation of just the board itself. This should disentangle your current inheritance structure a bit.

On a secondary note, you might want to separate the part of makeboard() which initializes the board into a separate clear() function. If you then have it called by the c'tor rather than makeboard(), follwed by a call to updateboard(), it will allow you to eliminate makeboard() entirely.

Edited 4 Years Ago by Schol-R-LEA

BTW, just as Woooee pointed out about updateboard() (which can just be update(), given that the board part is implied), you can simplify printboard() fairly easily:

def display(self):
    for i in range(0, 3):
        for j in range(0, 3):
            print(self.board[i][j])
        print() 

Edited 4 Years Ago by Schol-R-LEA

This question has already been answered. Start a new discussion instead.