Python Forum
Axis is out of bound error
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Axis is out of bound error
#1
Dear anyone who can help,

I have had a problem for many weeks with my code, it is suppose to play connect 4 against the computer. I have tried many things to fix it, the G_ stands for global. row count is the number of rows per column, column count is the number of columns on the board. The problem I have I keep getting is below

The error message I get is:

return board[G_row_count-1][col] == 0
IndexError: index 8 is out of bounds for axis 0 with size 8

#relevent moduals are being imported into the python IDLE
import numpy as np
import pygame
import pygame.camera
import system as sys
import math
import time
import random
from random import randrange

#pygame initialisation
pygame.init()

#defining global variables

# colours being defined for future use
GREEN = (0, 255, 0)
RED = (255, 0, 0)
GOLD = (255, 215, 0)
PINK = (255, 20, 147)
PURPLE = (128, 0, 128)
LIME = (0, 255, 0)
LIGHT_BLUE = (135, 206, 250)
YELLOW = (255, 255, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 168)
ORANGE = (255, 165, 0)

# NO. of rows per column - G_row_count is a global variable
G_row_count = 7
# NO. of columns in board - COLUMN_COUNT is a global variable
G_column_count = 8
# sets the size of a counter by the number of pixels
unit = 80
# sets with of pygame window
width = (G_column_count * unit)
# +1 to accomidate for placement bar
height = (G_row_count + 1) * unit
# create a size of the window
screen_size = (width, height)
#finds radius of counters
RADIUS = int(unit/2 - 5)

def full_check(L_slots_left, BACKGROUND, board, LabelFont, screen):
    #see if board has 0 spaces left
    if L_slots_left == 0:
    #informs player of draw
        #displays the a rectangle to cover up the counter at the top by putting a circle above it
        pygame.draw.rect(screen, BACKGROUND, (0, 0, width, unit))
        #set the variable to label and displays 'Draw!' in a green colour -  LabelFont is a pre-set varible name that holds the size of text and its font)
        label = LabelFont.render("Draw!", 1, GREEN)
        #updates the pygame window of changes made by the label and the rectangle
        screen.blit(label, (40,10))
        #waits for 2 seconds for user to see message
        pygame.time.wait(2000)
        #uses function board_reset() to reset the varibles and the board ready for another round
        board_reset()
        return board, LabelFont

def Colour_Scheme_A():
    #temporery variable until this becomes interactive
    colour_scheme = 'Pale'
    # select is a variable used so unless a colour_scheme has been chosen the game wont start
    select = False
    while select == False:
        if colour_scheme == 'Classic':
        #sets relavent objects of the program to a colour so the same code can be used later for diffrent colour schemes
            #sets the board colour to blue
            BOARD_COLOUR = BLUE
            # informs the while loop a colour scheme has been selected
            select = True
        elif colour_scheme == 'Funky':
            #sets the board colour to orange
            BOARD_COLOUR = ORANGE
            # informs the while loop a colour scheme has been selected
            select = True
        elif colour_scheme == 'Pale':
            #sets the board colour to pink
            BOARD_COLOUR = PINK
            # informs the while loop a colour scheme has been selected
            select = True
    return BOARD_COLOUR

def Colour_Scheme_B():
    #temporery variable until this becomes interactive
    colour_scheme = 'Pale'
    # select is a variable used so unless a colour_scheme has been chosen the game wont start
    select = False
    while select == False:
        if colour_scheme == 'Classic':
        #sets relavent objects of the program to a colour so the same code can be used later for diffrent colour schemes
            #sets player 1 counter to red
            COUNTER_COLOUR_1 = RED
            # informs the while loop a colour scheme has been selected
            select = True
        elif colour_scheme == 'Funky':
            #sets player 1 counter to purple
            COUNTER_COLOUR_1 = PURPLE
            # informs the while loop a colour scheme has been selected
            select = True
        elif colour_scheme == 'Pale':
            #sets player 1 counter to lime
            COUNTER_COLOUR_1 = LIME
            # informs the while loop a colour scheme has been selected
            select = True
    return COUNTER_COLOUR_1

def Colour_Scheme_C():
    #temporery variable until this becomes interactive
    colour_scheme = 'Pale'
    # select is a variable used so unless a colour_scheme has been chosen the game wont start
    select = False
    while select == False:
        if colour_scheme == 'Classic':
        #sets relavent objects of the program to a colour so the same code can be used later for diffrent colour schemes
            #sets player 1 counter to red
            COUNTER_COLOUR_2 = RED
            # informs the while loop a colour scheme has been selected
            select = True
        elif colour_scheme == 'Funky':
            #sets player 1 counter to purple
            COUNTER_COLOUR_2 = PURPLE
            # informs the while loop a colour scheme has been selected
            select = True
        elif colour_scheme == 'Pale':
            #sets player 1 counter to lime
            COUNTER_COLOUR_2 = LIME
            # informs the while loop a colour scheme has been selected
            select = True
    return COUNTER_COLOUR_2

def Colour_Scheme_D():
    #temporery variable until this becomes interactive
    colour_scheme = 'Pale'
    # select is a variable used so unless a colour_scheme has been chosen the game wont start
    select = False
    while select == False:
        if colour_scheme == 'Classic':
        #sets relavent objects of the program to a colour so the same code can be used later for diffrent colour schemes
            #sets player 1 counter to red
            BACKGROUND = BLACK
            # informs the while loop a colour scheme has been selected
            select = True
        elif colour_scheme == 'Funky':
            #sets player 1 counter to purple
            BACKGROUND = BLACK
            # informs the while loop a colour scheme has been selected
            select = True
        elif colour_scheme == 'Pale':
            #sets player 1 counter to lime
            BACKGROUND = BLACK
            # informs the while loop a colour scheme has been selected
            select = True
    return BACKGROUND
        
def board_reset():
    #resets the 2D array to all 0's 
    board = Zero_the_board()
    #resets to player 1's turn
    turn = 1
    return turn, board

def font():
    #set font for later on use for declaring a window
    Select_Font = pygame.font.SysFont('arial', 75)
    return Select_Font

def cover(BACKGROUND, screen):
    # This is a library function built in which displays the selected shape - this case a rectangle
    pygame.draw.rect(screen, BACKGROUND, (0, 0, width, unit))
    # updates the pygame window
    update()

def Zero_the_board():
    row_number = G_row_count + 1
    column_number = G_column_count
    # board 2D array is set zeroing by using np as a abreviation of numpy
    board = np.zeros((row_number,column_number))
    return board

def drop_piece(board, row, col, piece):
    #the value of the piece is setting the value of  that row and column in the 2D array board
    board[row][col] = piece

def location_validation(board, col):
    #removes a row and makes this the next avaliable location in that column
    return board[G_row_count-1][col] == 0

def get_next_open_row(board, col):
    #searches every row in the column
    for r in range(G_row_count):
        #if a row is free then r will be true
        if board[r][col] == 0:
            return r

def player_altinator(turn):
    #if player 1's turn change turn to 2 so it is player 2's turn next time round
    if turn == 1:
        turn = 2
    #if player 2's turn change turn to 1 so it is player 1's turn next time round
    elif turn == 2:
        turn = 1
    #returns the player who plays next
    return turn

def update():
    pygame.display.update()

def winning_move_check(board, piece):
    #check all locations
    for c in range(G_column_count-3):
        for r in range(G_row_count-3):
            if board[r][c] == piece and board[r][c+1] == piece and board[r][c+2] == piece and board[r][c+3] == piece:
                return True
    #check verticle locations
    for c in range(G_column_count -3):
            for r in range(G_row_count):
                if board[r][c] == piece and board[r+1][c] == piece and board[r+2][c] == piece and board[r+3][c] == piece:
                    return True
    #check for positivly sloped diagonal locations
    for c in range(G_column_count -3):
            for r in range(G_row_count -3):
                if board[r][c] == piece and board[r+1][c+1] == piece and board[r+2][c+2] == piece and board[r+3][c+3] == piece:
                    return True
    #check for negativly sloped diagonal locations
    for c in range(G_column_count -3):
            for r in range(3, G_row_count):
                if board[r][c] == piece and board[r-1][c+1] == piece and board[r-2][c+2] == piece and board[r-3][c+3] == piece:
                    return True 

def display_the_board(board, BOARD_COLOUR, COUNTER_COLOUR_1, COUNTER_COLOUR_2, BACKGROUND, screen):
    #background - displays solid squares then adds circles on top of them which are the slots for the counters
    for c in range(G_column_count):
        for r in range (G_row_count):
            # Draws game board
            pygame.draw.rect(screen, BOARD_COLOUR, (c*unit, r*unit+unit, unit, unit))
            # Draws circles in the board same colour as the background to looks like holes
            pygame.draw.circle(screen, BACKGROUND, (int(c*unit+unit/2), int(r*unit+unit+unit/2)), RADIUS)
    #counters being displayed at the top of the screen
    for c in range(G_column_count):
        for r in range(G_row_count):
            if board[r][c] == 1:
                # Draws counter of player 1 in top bar
                pygame.draw.circle(screen, COUNTER_COLOUR_1, (int(c*unit+unit/2), height-int(r*unit+unit/2)), RADIUS)
            elif board[r][c] == 2:
                # Draws counter of player 2 in top bar
                pygame.draw.circle(screen, COUNTER_COLOUR_2, (int(c*unit+unit/2), height-int(r*unit+unit/2)), RADIUS)
    update()
    return BOARD_COLOUR, COUNTER_COLOUR_1, COUNTER_COLOUR_2, BACKGROUND

def main_code():
    # Code starts
    # pygame window opens
    screen = pygame.display.set_mode(screen_size)
    # start off on player 1's turn
    turn = 1
    # sets font to desired font type
    LabelFont = font()
    # set board colour scheme
    BOARD_COLOUR = Colour_Scheme_A()
    COUNTER_COLOUR_1 =  Colour_Scheme_B()
    COUNTER_COLOUR_2 = Colour_Scheme_C()
    BACKGROUND = Colour_Scheme_D()
    # Creates the board
    board = Zero_the_board()
    # outputs board on pygame window
    display_the_board(board, BOARD_COLOUR, COUNTER_COLOUR_1, COUNTER_COLOUR_2, BACKGROUND, screen)
    update()
    # resets the number of empty slots to maximum
    L_slots_left = (G_row_count * G_column_count)
    # sets the variable to end game to false before game starts
    game_over = False
    # while to end game if game_over is true
    while not game_over:
        # activates the x close button on pygame window
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()

            # Have a circle appear over the mouse pointer
            if event.type == pygame.MOUSEMOTION:
                # new rectangle is displayed to no previous circles appear when currant circle is drawn
                pygame.draw.rect(screen, BACKGROUND, (0, 0, width, unit))
                posx = event.pos[0]
                if turn == 1:
                    # draw circle at the top to follow the mouse pointer for when player 1 using it - using varible SIZE (predesignated width and height of a block used by a counter)
                    pygame.draw.circle(screen, COUNTER_COLOUR_1, (posx, int(unit / 2)), RADIUS)
                elif turn == 2:
                    # draw circle at the top to follow the mouse pointer for when player 2 using it - using varible SIZE (predesignated width and height of a block used by a counter)
                    pygame.draw.circle(screen, COUNTER_COLOUR_2, (posx, int(unit / 2)), RADIUS)
                # updates screen of changes
                update()

            # if player 1's turn
            if turn == 1:
                # if mouse clicks the the following if statement will be true
                if event.type == pygame.MOUSEBUTTONDOWN:
                    # gets postion of mouse at time of click
                    posx = event.pos[0]
                    # rounds the exact place where the click occured to the nearest column
                    col = int(math.floor(posx / unit))
                    # check if the location selected is a valid/empty place on the board
                    if location_validation(board, col):
                        # uses function get_next_open_row to find the next empty space in that column
                        row = get_next_open_row(board, col)
                        # puts the piece in the 2D array to take that as a location
                        drop_piece(board, row, col, 1)
                        # check if 4 in row is completed
                        if winning_move_check(board, 1):
                            # displays a rectangle over the top bar so the counter does not show when the text appears
                            cover(BACKGROUND, screen)
                            # outputs the label of player 1 wins
                            label = LabelFont.render("Player 1 Wins!", 1, COUNTER_COLOUR_1)
                            # updates changes on the screen
                            screen.blit(label, (40,10))
                            # informs the game loop to end as the game has finished
                            game_over = True
            elif turn == 2:
                # CPU takes a turn
                # randomly selects a column to place its counter in
                col = random.randint(1, G_column_count)
                # check if the location selected is a valid/empty place on the board
                if location_validation(board, col):
                    # uses function get_next_open_row to find the next empty space in that column
                    row = get_next_open_row(board, col)
                    # puts the piece in the 2D array to take that as a location
                    drop_piece(board, row, col, 2)
                    # check if 4 in row is completed
                    if winning_move_check(board, 2):
                        # displays a rectangle over the top bar so the counter does not show when the text appears
                        cover(BACKGROUND, screen)
                        # outputs the label of player 2 wins
                        label = LabelFont.render("Player 2 Wins!", 1, COUNTER_COLOUR_2)
                        # updates changes on the screen
                        screen.blit(label, (40,10))
                        # informs the game loop to end as the game has finished
                        game_over = True

            # player altinator function is called
            turn = player_altinator(turn)

            # counter to remove 1 after every time a counter is placed to determin the a draw?
            L_slots_left = (L_slots_left - 1)
            display_the_board(board, BOARD_COLOUR, COUNTER_COLOUR_1, COUNTER_COLOUR_2, BACKGROUND, screen) # Do i need this ?

            # Check if board is full
            full_check(L_slots_left, BACKGROUND, board, LabelFont, screen)

            if game_over:
                pygame.time.wait(5000)

#start game
main_code()
Any help would be much appreciated thanks
Reply
#2
IndexError: index 8 is out of bounds for axis 0 with size 8
Indexing starts with position "0" not 1, so the 8th spot in the index is numbered "7".
Reply
#3
Did I not address the problem with line 188

return board[G_row_count-1][col] == 0
If I didn't then what do I write to fix this error

Thanks for all of this help
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020