#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    8
    Rep Power
    0

    Implementing 2player in Tron bike game


    Hi all,

    I'm working on making the tron bike game using Tkinter in python. For those of you that are not familiar with it, the point of the game is to destroy the other player's bike by making it cross the path of yours. Both players control their bikes' using different keys on the same keyboard ie. player one uses up, down, left, right, and player 2 uses w, a , s, d. Right now I have the first players bike running perfectly, but when I try to add the other one I run into problems. I thought it would be as simple as creating the same functions that moved the first bike but with different variable names but I was running into weird bugs. Does anybody have a good idea as to how I could implement the second bike into this?
    thanks very much
    Code:
    import random
    from Tkinter import *
    
    def mousePressed(event):
        redrawAll()
    
    def keyPressed(event):
        canvas.data.ignoreNextTimerEvent = True 
        if (event.char == "q"):
            gameOver()
        elif (event.char == "r"):
            init()
        elif (event.char == "d"):
            canvas.data.inDebugMode = not canvas.data.inDebugMode
        if (canvas.data.isGameOver == False):
            if (event.keysym == "Up"):
                moveBike(-1, 0)
            elif (event.keysym == "Down"):
                moveBike(+1, 0)
            elif (event.keysym == "Left"):
                moveBike(0,-1)
            elif (event.keysym == "Right"):
                moveBike(0,+1)
            elif (event.keysym == "f"):
                moveBike2(0,-1)
            elif (event.keysym == "g"):
                moveBike2(+1,0)
            elif (event.keysym == "t"):
                moveBike2(-1,0)
            elif (event.keysym == "h"):
                moveBike2(0, +1)
        redrawAll()
        
    
            
    def moveBike(drow, dcol):
        canvas.data.bikeDrow = drow 
        canvas.data.bikeDcol = dcol
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        bikeRow = canvas.data.bikeRow
        bikeCol = canvas.data.bikeCol
        newBikeRow = bikeRow + drow
        newBikeCol = bikeCol + dcol
        canvas.data.path1.append((newBikeRow, newBikeCol))
        if ((newBikeRow < 0) or (newBikeRow >= rows) or
            (newBikeCol < 0) or (newBikeCol >= cols)):
            gameOver()
        elif (tronBoard[newBikeRow][newBikeCol] > 0):
            gameOver()
        elif (tronBoard[newBikeRow][newBikeCol] == 0):
            tronBoard[newBikeRow][newBikeCol] = 1 + tronBoard[bikeRow][bikeCol];
            canvas.data.bikeRow = newBikeRow
            canvas.data.bikeCol = newBikeCol
    
    
    
    def gameOver():
        canvas.data.isGameOver = True
    
    def timerFired():
        tronBoard = canvas.data.tronBoard
        ignoreThisTimerEvent = canvas.data.ignoreNextTimerEvent
        canvas.data.ignoreNextTimerEvent = False
        if ((canvas.data.isGameOver == False) and
            (ignoreThisTimerEvent == False)):
            drow = canvas.data.bikeDrow
            dcol = canvas.data.bikeDcol
            moveBike(drow, dcol)
            
            redrawAll()
        delay = 50
        drawBikePath()
        canvas.after(delay, timerFired)
    
    
        
    
    def redrawAll():
        #drawBikePath1()
        cx = canvas.data.canvasWidth/2
        cy = canvas.data.canvasHeight/2
        if (canvas.data.isGameOver == True):
            canvas.create_text(cx, cy, text="Game Over!", fill = "red",
                               font=("Helvetica", 32, "bold"))
        
    
    
    
    def drawBikePath():
        row,col = canvas.data.path1[-1]
        margin = canvas.data.margin
        cellSize = canvas.data.cellSize
        left = margin + col *cellSize
        right = left + cellSize
        top = margin + row*cellSize
        bottom = top + cellSize
        canvas.create_rectangle(left, top, right, bottom, fill="green")
    
    def drawBike2Path():
        row,col = canvas.data.path2[-1]
        margin = canvas.data.margin
        cellSize = canvas.data.cellSize
        left = margin + col *cellSize
        right = left + cellSize
        top = margin + row*cellSize
        bottom = top + cellSize
        canvas.create_rectangle(left, top, right, bottom, fill="purple")
            
    def drawTronBoard():
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        for row in range(rows):
            for col in range(cols):
                drawTronCell(tronBoard, row, col)
    
    def drawTronCell(tronBoard, row, col):
        margin = canvas.data.margin
        cellSize = canvas.data.cellSize
        bikeRow = canvas.data.bikeRow
        bikeCol = canvas.data.bikeCol
        left = margin + col * cellSize
        right = left + cellSize
        top = margin + row * cellSize
        bottom = top + cellSize
        canvas.create_rectangle(left, top, right, bottom, fill="black", outline="brown")
        if (tronBoard[row][col] > 0):
            canvas.create_rectangle(left, top, right, bottom, fill="green")
        if (canvas.data.inDebugMode == True):
            canvas.create_text(left+cellSize/2,top+cellSize/2,
                               text=str(tronBoard[row][col]),font=("Helvatica", 14, "bold"))
    
    def loadTronBoard():
        rows = canvas.data.rows
        cols = canvas.data.cols
        tronBoard = [ ]
        for row in range(rows): tronBoard += [[0] * cols]
        tronBoard[rows/2][cols/8] = 1
        tronBoard[rows/2][cols-cols/8] = -1
        canvas.data.tronBoard = tronBoard
        findBike()
        
    
    
    
    def findBike():
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        bikeRow = 0
        bikeCol = 0
        for row in range(rows):
            for col in range(cols):
                if (tronBoard[row][col] > tronBoard[bikeRow][bikeCol]):
                    bikeRow = row
                    bikeCol = col
        canvas.data.bikeRow = bikeRow
        canvas.data.bikeCol = bikeCol
    
    
    
    def printInstructions():
        print "Press 'd' for debug mode."
        print "Press 'r' to restart."
    
    def init():
        printInstructions()
        loadTronBoard()
        canvas.data.inDebugMode = False
        canvas.data.isGameOver = False
        canvas.data.path1 = []
        canvas.data.path2 = []
        canvas.data.bikeDrow = +1
        canvas.data.bikeDcol = 0
        canvas.data.bike2Drow = -1
        canvas.data.bike2Dcol = 0
        canvas.data.ignoreNextTimerEvent = False
        drawTronBoard()
        redrawAll()
    
    ########### copy-paste below here ###########
    
    def run(rows, cols):
        # create the root and the canvas
        global canvas
        root = Tk()
        margin = 5
        cellSize = 15
        canvasWidth = 2*margin + cols*cellSize
        canvasHeight = 2*margin + rows*cellSize
        canvas = Canvas(root, width=canvasWidth, height=canvasHeight)
        canvas.pack()
        # Store canvas in root and in canvas itself for callbacks
        root.canvas = canvas.canvas = canvas
        # Set up canvas data and call init
        class Struct: pass
        canvas.data = Struct()
        canvas.data.margin = margin
        canvas.data.cellSize = cellSize
        canvas.data.canvasWidth = canvasWidth
        canvas.data.canvasHeight = canvasHeight
        canvas.data.rows = rows
        canvas.data.cols = cols
        init()
        # set up events
        root.bind("<Button-1>", mousePressed)
        root.bind("<Key>", keyPressed)
        timerFired()
        # and launch the app
        root.mainloop()  # This call BLOCKS (so your program waits until you close the window!)
    
    run(40,40)
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    8
    Rep Power
    0
    here is my attempt at implementing the other bike. as you can see, the controls don't work for the second bike, among other things.

    Code:
    import random
    from Tkinter import *
    
    def mousePressed(event):
        redrawAll()
    
    def keyPressed(event):
        canvas.data.ignoreNextTimerEvent = True 
        if (event.char == "q"):
            gameOver()
        elif (event.char == "r"):
            init()
        elif (event.char == "d"):
            canvas.data.inDebugMode = not canvas.data.inDebugMode
        if (canvas.data.isGameOver == False):
            if (event.keysym == "Up"):
                moveBike(-1, 0)
            elif (event.keysym == "Down"):
                moveBike(+1, 0)
            elif (event.keysym == "Left"):
                moveBike(0,-1)
            elif (event.keysym == "Right"):
                moveBike(0,+1)
            elif (event.keysym == "f"):
                moveBike2(0,-1)
            elif (event.keysym == "g"):
                moveBike2(+1,0)
            elif (event.keysym == "t"):
                moveBike2(-1,0)
            elif (event.keysym == "h"):
                moveBike2(0, +1)
        redrawAll()
        
    def moveBike2(drow, dcol):
        canvas.data.bike2Drow = drow 
        canvas.data.bike2Dcol = dcol
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        bike2Row = canvas.data.bike2Row
        bike2Col = canvas.data.bike2Col
        newBike2Row = bike2Row + drow
        newBike2Col = bike2Col + dcol
        canvas.data.path2.append((newBike2Row, newBike2Col))
        
        if ((newBike2Row < 0) or (newBike2Row >= rows) or
            (newBike2Col < 0) or (newBike2Col >= cols)):
            gameOver()
        elif (tronBoard[newBike2Row][newBike2Col] > 0):
            gameOver()
        elif (tronBoard[newBike2Row][newBike2Col] == 0):
            tronBoard[newBike2Row][newBike2Col] = tronBoard[bike2Row][bike2Col] - 1
            canvas.data.bike2Row = newBike2Row
            canvas.data.bike2Col = newBike2Col
            
    def moveBike(drow, dcol):
        canvas.data.bikeDrow = drow 
        canvas.data.bikeDcol = dcol
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        bikeRow = canvas.data.bikeRow
        bikeCol = canvas.data.bikeCol
        newBikeRow = bikeRow + drow
        newBikeCol = bikeCol + dcol
        canvas.data.path1.append((newBikeRow, newBikeCol))
        if ((newBikeRow < 0) or (newBikeRow >= rows) or
            (newBikeCol < 0) or (newBikeCol >= cols)):
            gameOver()
        elif (tronBoard[newBikeRow][newBikeCol] > 0):
            gameOver()
        elif (tronBoard[newBikeRow][newBikeCol] == 0):
            tronBoard[newBikeRow][newBikeCol] = 1 + tronBoard[bikeRow][bikeCol];
            canvas.data.bikeRow = newBikeRow
            canvas.data.bikeCol = newBikeCol
    ##    else:
    ##        tronBoard[newBikeRow][newBikeCol] = 1 + tronBoard[bikeRow][bikeCol];
    ##        canvas.data.bikeRow = newBikeRow
    ##        canvas.data.bikeCol = newBikeCol
            #removeTail()
    
    
    
    def gameOver():
        canvas.data.isGameOver = True
    
    def timerFired():
        tronBoard = canvas.data.tronBoard
        ignoreThisTimerEvent = canvas.data.ignoreNextTimerEvent
        canvas.data.ignoreNextTimerEvent = False
        if ((canvas.data.isGameOver == False) and
            (ignoreThisTimerEvent == False)):
            drow = canvas.data.bikeDrow
            dcol = canvas.data.bikeDcol
            #moveBike(drow, dcol)
            moveBike2(drow, dcol)
            redrawAll()
        delay = 50
        #drawBikePath()
        drawBike2Path()
        canvas.after(delay, timerFired)
    
    
        
    
    def redrawAll():
        #drawBikePath1()
        cx = canvas.data.canvasWidth/2
        cy = canvas.data.canvasHeight/2
        if (canvas.data.isGameOver == True):
            canvas.create_text(cx, cy, text="Game Over!", fill = "red",
                               font=("Helvetica", 32, "bold"))
        
    
    
    
    def drawBikePath():
        row,col = canvas.data.path1[-1]
        margin = canvas.data.margin
        cellSize = canvas.data.cellSize
        left = margin + col *cellSize
        right = left + cellSize
        top = margin + row*cellSize
        bottom = top + cellSize
        canvas.create_rectangle(left, top, right, bottom, fill="green")
    
    def drawBike2Path():
        row,col = canvas.data.path2[-1]
        margin = canvas.data.margin
        cellSize = canvas.data.cellSize
        left = margin + col *cellSize
        right = left + cellSize
        top = margin + row*cellSize
        bottom = top + cellSize
        canvas.create_rectangle(left, top, right, bottom, fill="purple")
            
    def drawTronBoard():
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        for row in range(rows):
            for col in range(cols):
                drawTronCell(tronBoard, row, col)
    
    def drawTronCell(tronBoard, row, col):
        margin = canvas.data.margin
        cellSize = canvas.data.cellSize
        bikeRow = canvas.data.bikeRow
        bikeCol = canvas.data.bikeCol
        left = margin + col * cellSize
        right = left + cellSize
        top = margin + row * cellSize
        bottom = top + cellSize
        canvas.create_rectangle(left, top, right, bottom, fill="black", outline="brown")
        if (tronBoard[row][col] > 0):
            canvas.create_rectangle(left, top, right, bottom, fill="green")
    ##    elif (tronBoard[row][col] < 0):
    ##        canvas.create_rectangle(left, top, right, bottom, fill="green")
    ##    if (tronBoard[row][col]==tronBoard[bikeRow][bikeCol]):
    ##        canvas.create_rectangle(left, top, right, bottom, fill = "purple")
        if (canvas.data.inDebugMode == True):
            canvas.create_text(left+cellSize/2,top+cellSize/2,
                               text=str(tronBoard[row][col]),font=("Helvatica", 14, "bold"))
    
    def loadTronBoard():
        rows = canvas.data.rows
        cols = canvas.data.cols
        tronBoard = [ ]
        for row in range(rows): tronBoard += [[0] * cols]
        tronBoard[rows/2][cols/8] = 1
        tronBoard[rows/2][cols-cols/8] = -1
        canvas.data.tronBoard = tronBoard
        findBike()
        findBike2()
        #placeBoost()
    
    def placeBoost():
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        while True:
            row = random.randint(0,rows-1)
            col = random.randint(0,cols-1)
            if (tronBoard[row][col] == 0):
                break
        tronBoard[row][col] = -1
    
    def findBike():
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        bikeRow = 0
        bikeCol = 0
        for row in range(rows):
            for col in range(cols):
                if (tronBoard[row][col] > tronBoard[bikeRow][bikeCol]):
                    bikeRow = row
                    bikeCol = col
        canvas.data.bikeRow = bikeRow
        canvas.data.bikeCol = bikeCol
    
    def findBike2():
        tronBoard = canvas.data.tronBoard
        rows = len(tronBoard)
        cols = len(tronBoard[0])
        bike2Row = 0
        bike2Col = 0
        for row in range(rows):
            for col in range(cols):
                if (tronBoard[row][col] < tronBoard[bike2Row][bike2Col]):
                    bike2Row = row
                    bike2Col = col
        canvas.data.bike2Row = bike2Row
        canvas.data.bike2Col = bike2Col
    
    def printInstructions():
        print "Press 'd' for debug mode."
        print "Press 'r' to restart."
    
    def init():
        printInstructions()
        loadTronBoard()
        canvas.data.inDebugMode = False
        canvas.data.isGameOver = False
        canvas.data.path1 = []
        canvas.data.path2 = []
        canvas.data.bikeDrow = +1
        canvas.data.bikeDcol = 0
        canvas.data.bike2Drow = -1
        canvas.data.bike2Dcol = 0
        canvas.data.ignoreNextTimerEvent = False
        drawTronBoard()
        redrawAll()
    
    ########### copy-paste below here ###########
    
    def run(rows, cols):
        # create the root and the canvas
        global canvas
        root = Tk()
        margin = 5
        cellSize = 15
        canvasWidth = 2*margin + cols*cellSize
        canvasHeight = 2*margin + rows*cellSize
        canvas = Canvas(root, width=canvasWidth, height=canvasHeight)
        canvas.pack()
        # Store canvas in root and in canvas itself for callbacks
        root.canvas = canvas.canvas = canvas
        # Set up canvas data and call init
        class Struct: pass
        canvas.data = Struct()
        canvas.data.margin = margin
        canvas.data.cellSize = cellSize
        canvas.data.canvasWidth = canvasWidth
        canvas.data.canvasHeight = canvasHeight
        canvas.data.rows = rows
        canvas.data.cols = cols
        init()
        # set up events
        root.bind("<Button-1>", mousePressed)
        root.bind("<Key>", keyPressed)
        timerFired()
        # and launch the app
        root.mainloop()  # This call BLOCKS (so your program waits until you close the window!)
    
    run(40,40)
  4. #3
  5. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,997
    Rep Power
    481
    Code:
    '''
    defects:
        border needs redrawn, or eliminate over-drawing it.
        pressing a key changes direction
        crash detection
        1 function handles all bikes.  Eliminate duplicate code!!!!
        drawTronBoard has quadratic instead of linear run time.  You draw by area rather than by perimeter.
        Enable both "light cycles"
    
    removed debugging that did not seem to work anyway
    removed the zoom pack feature
    changed the key press events to affect steering, not speed, eliminating your ignoreTimer logic.
    What the heck was "findCycle" doing?  You did not keep track of them????  This version maintains their location.
    
    Timer delay: you had 50, I am slow so I changed it to 200.
    
    I would implement boost by reducing the timer fired delay to 10, put a
    counter for each light cycle, and then each time the counter mod 5 is
    zero move the cycles by a step.  If a cycle hits the boost change the
    modulus to 4.  Anyway, I have a simple implementation for this in my
    head but my woman wants me now so I will post rather than implement.
    '''
    
    import random
    from Tkinter import *
    
    controls = dict(
        Up=   (0,-1, 0),
        Down= (0,+1, 0),
        Left= (0, 0,-1),
        Right=(0, 0,+1),
        f=    (1, 0,-1),
        g=    (1,+1, 0),
        t=    (1,-1, 0),
        h=    (1, 0,+1),
        )
    
    def keyPressed(event):
        global moves
        if event.char and (event.char in 'qr'):
            if 'q' == event.char:
                gameOver()
            else:
                init()
        if not canvas.data.GAMEISOVER:
            try:
                control = controls[event.keysym]
            except KeyError:
                pass
            else:
                steer(*control)
    
    def steer(BIKE,DR,DC):
        canvas.data.BIKEHEADING[BIKE] = (DR, DC,)
    
    def gameOver():
        canvas.data.GAMEISOVER = True
    
    def vadd(A,B):
        return [a+b for (a,b,) in zip(A,B)]
    
    def timerFired():
        tronBoard = canvas.data.tronBoard
        if not canvas.data.GAMEISOVER:
            (P0, P1,) = canvas.data.BIKEPOSITION
            (H0, H1,) = canvas.data.BIKEHEADING
            canvas.data.BIKEPOSITION = (vadd(P0,H0,),vadd(P1,H1,),)
            rows = canvas.data.rows
            cols = canvas.data.cols
            (P0, P1,) = canvas.data.BIKEPOSITION
            if not ((0 <= P0[0] < rows) and (0 <= P0[1] < cols) and (0 <= P1[0] < rows) and (0 <= P1[1] < cols)):
                gameOver()
            else:
                canvas.data.GAMEISOVER = (1 == abs(tronBoard[P0[0]][P0[1]])) or (1 == abs(tronBoard[P1[0]][P1[1]]))
                tronBoard[P0[0]][P0[1]] =  1
                tronBoard[P1[0]][P1[1]] = -1
        redrawAll()
        delay = 200
        canvas.after(delay, timerFired)
    
    def redrawAll():
        if canvas.data.GAMEISOVER:
            cx = canvas.data.canvasWidth/2
            cy = canvas.data.canvasHeight/2
            canvas.create_text(cx, cy, text="Game Over!", fill = "red", font=("Helvetica", 32, "bold"))
        else:
            (P0, P1,) = canvas.data.BIKEPOSITION
            drawTronCell('green',*P0)
            drawTronCell('purple',*P1)
    
    def drawTronCell(color, row, col):
        margin = canvas.data.margin
        cellSize = canvas.data.cellSize
        left = margin + col * cellSize
        right = left + cellSize
        top = margin + row * cellSize
        bottom = top + cellSize
        canvas.create_rectangle(left, top, right, bottom, fill=color)
    
    def printInstructions():
        print 'arrows steer one bike, tfgh steer the other.'
        print "Press 'r' to restart."
    
    def loadTronBoard():
        rows = canvas.data.rows
        cols = canvas.data.cols
        tronBoard = [[0] * cols for row in range(rows)]
        (P0, P1,) = canvas.data.BIKEPOSITION
        tronBoard[P0[0]][P0[1]] =  1
        tronBoard[P1[0]][P1[1]] = -1
        canvas.data.tronBoard = tronBoard
    
    def drawTronBoard():
        tronBoard = canvas.data.tronBoard
        W = canvas.data.canvasWidth
        H = canvas.data.canvasHeight
        M = canvas.data.margin
        A = HALFM = M//2
        CELLSIZE = canvas.data.cellSize
        canvas.create_line(A,A, W-A,A, W-A,H-A, A,H-A, A,A, width=M+1, fill='gray')
        canvas.create_rectangle(M,M, W-M,H-M, fill='black')
        for X in range(M,W-M+1,CELLSIZE):
            canvas.create_line(X,M, X,H-M, fill='brown')
        for Y in range(M,H-M+1,CELLSIZE):
            canvas.create_line(M,Y, W-M,Y, fill='brown')
    
    def init():
        printInstructions()
        rows = canvas.data.rows
        cols = canvas.data.cols
        canvas.data.BIKEHEADING = [(1,0,),(-1,0,),]
        canvas.data.BIKEPOSITION= [(rows//2,cols//8,),(rows//2,cols-cols//8,),]
        loadTronBoard()
        drawTronBoard()
        canvas.data.GAMEISOVER = False
        redrawAll()
    
    def run(rows, cols):
        global canvas
        root = Tk()
        margin = 5
        cellSize = 15
        canvasWidth = 2*margin + cols*cellSize
        canvasHeight = 2*margin + rows*cellSize
        canvas = Canvas(root, width=canvasWidth, height=canvasHeight)
        canvas.pack()
        root.canvas = canvas.canvas = canvas
        class Struct: pass
        canvas.data = Struct()
        canvas.data.margin = margin
        canvas.data.cellSize = cellSize
        canvas.data.canvasWidth = canvasWidth
        canvas.data.canvasHeight = canvasHeight
        canvas.data.rows = rows
        canvas.data.cols = cols
        init()
        root.bind("<Key>", keyPressed)
        timerFired()
        root.mainloop()
    
    run(40,40)
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo