Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help with a bug
#1
Hello! This is my first post, so please excuse any issues with the formatting.

I am very new to coding and am trying to teach myself python. I've been working on a connect 4 game, and there is a bug that causes the little circle to be partially hidden when you click and the congratulations text to be hidden. There is also something small at the bottom, the 'holes' for the pieces to fall into don't come all the way to the bottom of the 'board'. It's nothing big, but I would like to know if anyone has any ideas to fix this :) Thank you!!

This is the code, below, and the link to the site to see it on.

https://replit.com/@MadelineCovil/Connec...ha#main.py

So a few notes---
  1. Where the 'piece' should be, there will be a 1 or a 2. It makes the computer see what they should put on.
  2. In case something goes wrong, the beta version can be put into this script and the video can rewind starting at 31:31. Continue from there.
  3. Pass is a placeholder. It allows you to run your program without errors and its for when you know you need somehting, don't know how to build it yet, but need it.
  4. To indent a large amount of code while keeping formatting, select it and push tab as many times as is needed. Good lord, I'm so stupid.

import numpy as np
import pygame
import sys
import math
#Global variables--to eliminate 'magic numbers'--the numbers that seem to come from nowhere.
ROW_COUNT=6
COLUMN_COUNT=7
#We are using this as an RGB value.
BLUE=(0,0,200)
BLACK=(0,0,0)
RED=(255,0,0)
YELLOW=(255,255,0)

def create_board():
  #The line above creates a function. The line below makes a matrix of sorts. The return line gives us that.
  board=np.zeros((ROW_COUNT,COLUMN_COUNT)) #The 6,7 is the dimentions of the play board. Six rows, seven columns.
  return board

def drop_piece(board,row,selection,piece):
  #This will cause the piece to appear. 
  #One equal sign is to assign a thing, not reassign it.
  board[row][selection]=piece
  #So apparently pass is for one of those things that you know you need but aren't quite ready to build.

def validate_location(board, selection):
  #This space will give the computer to make sure the input for location is valid. It looks at the top row (5) and the user column to determine whether or not there is a free space in that row.
  return board[ROW_COUNT-1][selection]==0

def get_next_open_row(board,selection):
  #I think this helps the numbers stack. It reads if a spot is still empty or not and puts the next thing in the column as above.
  for r in range(ROW_COUNT):
    if board[r][selection]==0:
      return r

def print_board(board):
  #All this is going to do is change the orientation. Without this, the numbers print upside down. the pieces don't fall the right way, they start at the top and move down. It flips the way we view the board.
 print( np.flip(board,0)) #The 0 in this case is telling it to flip over the x axis I believe.

def winning(board,piece):
  #check all horizontal locations for 4
  for c in range(COLUMN_COUNT-3):
    for r in range(ROW_COUNT):
      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 all vertical locations for 4
  for c in range(COLUMN_COUNT):
    for r in range(ROW_COUNT-3):
      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 all / locations for 4
  for c in range(COLUMN_COUNT-3):
    for r in range(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 all \ locations for 4
  for c in range(COLUMN_COUNT-3):
    for r in range(3,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 draw_board(board):
  for c in range(COLUMN_COUNT):
    for r in range(ROW_COUNT):
      pygame.draw.rect(screen, BLUE, (c*SQUARE_SIZE, r*SQUARE_SIZE+SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
      pygame.draw.circle(screen,BLACK,((c*SQUARE_SIZE+SQUARE_SIZE/2),(r*SQUARE_SIZE+SQUARE_SIZE/2)),RADIUS)

  for c in range(COLUMN_COUNT):
    for r in range(ROW_COUNT):
      if board[r][c]==1:
        pygame.draw.circle(screen,RED,((c*SQUARE_SIZE+SQUARE_SIZE/2),height-(r*SQUARE_SIZE+SQUARE_SIZE/2)),RADIUS)
      elif board[r][c]==2:
        pygame.draw.circle(screen,YELLOW,((c*SQUARE_SIZE+SQUARE_SIZE/2),height-(r*SQUARE_SIZE+SQUARE_SIZE/2)),RADIUS)
  pygame.display.update()

##The next line starts the starting board
board=create_board()
print_board(board)
#We want to play as long as the game is still going. Game over is our new variable. We set it to false.With a capital, apparently. The while not part means if it's not true. 
game_over=False
#To differentiate between player 1 and player 2....
turn=0
pygame.init()
SQUARE_SIZE=100 #This sizing works in pixles. This is the game screen size.
width=COLUMN_COUNT * SQUARE_SIZE
height=(ROW_COUNT+1) * SQUARE_SIZE
RADIUS=int(SQUARE_SIZE/2-5)
#The +1 adds the bar at the top.
screen_size=(width,height)
screen=pygame.display.set_mode(screen_size)
draw_board(board)
pygame.display.update()

myfont=pygame.font.SysFont("monospace",75)

while not game_over:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      sys.exit()
    if event.type==pygame.MOUSEMOTION:
      pygame.draw.rect(screen,BLACK,(0,0,width,SQUARE_SIZE))
      posx=event.pos[0]
      if turn==0:
        pygame.draw.circle(screen, RED, (posx,int(SQUARE_SIZE/2)), RADIUS)
      else:
        pygame.draw.circle(screen, YELLOW, (posx,int(SQUARE_SIZE/2)), RADIUS)
    pygame.display.update()
    if event.type == pygame.MOUSEBUTTONDOWN:
      print(event.pos) 
      #this asks for the player 1 input.
      if turn==0:
        posx = event.pos[0]
        selection=int(math.floor(posx/SQUARE_SIZE))
 
        if validate_location(board,selection):
          row=get_next_open_row(board,selection)
          drop_piece(board, row, selection, 1)
 
          if winning(board,1):
            label=myfont.render("PLAYER 1 WINS!!",1,RED)
            screen.blit(label,(40,10))
            game_over=True
 
      else:
        selection=posx = event.pos[0]
        selection=int(math.floor(posx/SQUARE_SIZE)) 
        if validate_location(board,selection):
          row=get_next_open_row(board,selection)
          drop_piece(board, row, selection, 2)
 
          if winning(board,2):
            label=myfont.render("PLAYER 2 WINS!!", 2, YELLOW)
            screen.blit(label,(40,10))
            game_over=True
 
      print_board(board)
      draw_board(board)
      turn+=1
      turn=turn % 2
      if game_over:
        pygame.time.wait(3000)
PS The little notes in there are entirely to tell me to know what each part is for, as I said, I am very new and need all of the things to tell me what each unfamiliar part does, you don't need to worry about it if you don't need to. :)

Larz60+ write Jan-05-2022, 05:08 PM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Fixed for you this time. Please use bbcode tags on future posts.
Reply
#2
I added line 63screen.fill (BLACK)to get rid of that little ghost crescent after each move.
I changed line 65 to for r in range(ROW_COUNT+1):to make rows go all the way to the bottom.
I added these lines to the end to display winning banner before exiting.
if game_over:
	pygame.time.wait(4000)
else :
	draw_board(board)
So... Here's everything so far:
import numpy as np
import pygame
import sys
import math
#Global variables--to eliminate 'magic numbers'--the numbers that seem to come from nowhere.
ROW_COUNT=6
COLUMN_COUNT=7
#We are using this as an RGB value.
BLUE=(0,0,200)
BLACK=(0,0,0)
RED=(255,0,0)
YELLOW=(255,255,0)
 
def create_board():
  #The line above creates a function. The line below makes a matrix of sorts. The return line gives us that.
  board=np.zeros((ROW_COUNT,COLUMN_COUNT)) #The 6,7 is the dimentions of the play board. Six rows, seven columns.
  return board
 
def drop_piece(board,row,selection,piece):
  #This will cause the piece to appear. 
  #One equal sign is to assign a thing, not reassign it.
  board[row][selection]=piece
  #So apparently pass is for one of those things that you know you need but aren't quite ready to build.
 
def validate_location(board, selection):
  #This space will give the computer to make sure the input for location is valid. It looks at the top row (5) and the user column to determine whether or not there is a free space in that row.
  return board[ROW_COUNT-1][selection]==0
 
def get_next_open_row(board,selection):
  #I think this helps the numbers stack. It reads if a spot is still empty or not and puts the next thing in the column as above.
  for r in range(ROW_COUNT):
    if board[r][selection]==0:
      return r
 
def print_board(board):
  #All this is going to do is change the orientation. Without this, the numbers print upside down. the pieces don't fall the right way, they start at the top and move down. It flips the way we view the board.
 print( np.flip(board,0)) #The 0 in this case is telling it to flip over the x axis I believe.
 
def winning(board,piece):
  #check all horizontal locations for 4
  for c in range(COLUMN_COUNT-3):
    for r in range(ROW_COUNT):
      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 all vertical locations for 4
  for c in range(COLUMN_COUNT):
    for r in range(ROW_COUNT-3):
      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 all / locations for 4
  for c in range(COLUMN_COUNT-3):
    for r in range(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 all \ locations for 4
  for c in range(COLUMN_COUNT-3):
    for r in range(3,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 draw_board(board):
  screen.fill (BLACK)
  for c in range(COLUMN_COUNT):
    for r in range(ROW_COUNT+1):
      pygame.draw.rect(screen, BLUE, (c*SQUARE_SIZE, r*SQUARE_SIZE+SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
      pygame.draw.circle(screen,BLACK,((c*SQUARE_SIZE+SQUARE_SIZE/2),(r*SQUARE_SIZE+SQUARE_SIZE/2)),RADIUS)
 
  for c in range(COLUMN_COUNT):
    for r in range(ROW_COUNT):
      if board[r][c]==1:
        pygame.draw.circle(screen,RED,((c*SQUARE_SIZE+SQUARE_SIZE/2),height-(r*SQUARE_SIZE+SQUARE_SIZE/2)),RADIUS)
      elif board[r][c]==2:
        pygame.draw.circle(screen,YELLOW,((c*SQUARE_SIZE+SQUARE_SIZE/2),height-(r*SQUARE_SIZE+SQUARE_SIZE/2)),RADIUS)
  pygame.display.update()
 
##The next line starts the starting board
board=create_board()
print_board(board)
#We want to play as long as the game is still going. Game over is our new variable. We set it to false.With a capital, apparently. The while not part means if it's not true. 
game_over=False
#To differentiate between player 1 and player 2....
turn=0
pygame.init()
SQUARE_SIZE=100 #This sizing works in pixles. This is the game screen size.
width=COLUMN_COUNT * SQUARE_SIZE
height=(ROW_COUNT+1) * SQUARE_SIZE
RADIUS=int(SQUARE_SIZE/2-5)
#The +1 adds the bar at the top.
screen_size=(width,height)
screen=pygame.display.set_mode(screen_size)
draw_board(board)
pygame.display.update()
 
myfont=pygame.font.SysFont("monospace",75)
 
while not game_over:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      sys.exit()
    if event.type==pygame.MOUSEMOTION:
      pygame.draw.rect(screen,BLACK,(0,0,width,SQUARE_SIZE))
      posx=event.pos[0]
      if turn==0:
        pygame.draw.circle(screen, RED, (posx,int(SQUARE_SIZE/2)), RADIUS)
      else:
        pygame.draw.circle(screen, YELLOW, (posx,int(SQUARE_SIZE/2)), RADIUS)
    pygame.display.update()
    if event.type == pygame.MOUSEBUTTONDOWN:
      print(event.pos) 
      #this asks for the player 1 input.
      if turn==0:
        posx = event.pos[0]
        selection=int(math.floor(posx/SQUARE_SIZE))
  
        if validate_location(board,selection):
          row=get_next_open_row(board,selection)
          drop_piece(board, row, selection, 1)
  
          if winning(board,1):
            draw_board(board)
            label=myfont.render("PLAYER 1 WINS!!",1,RED)
            screen.blit(label,(20,10))
            pygame.display.update ()
            game_over=True
  
      else:
        selection=posx = event.pos[0]
        selection=int(math.floor(posx/SQUARE_SIZE)) 
        if validate_location(board,selection):
          row=get_next_open_row(board,selection)
          drop_piece(board, row, selection, 2)
  
          if winning(board,2):
            label=myfont.render("PLAYER 2 WINS!!", 2, YELLOW)
            screen.blit(label,(40,10))
            game_over=True
  
      print_board(board)
      turn+=1
      turn=turn % 2
      if game_over:
        pygame.time.wait(4000)
      else :
        draw_board(board)
Reply
#3
Thank you so much for your help!! I am so grateful! It fixed it, thank you very much!!!!!
Reply
#4
We need to be happy. permit your self to pick happiness. if life was perfect, would you be satisfied? life is perfect due to the fact we create it with our choices. for the reason that we are able to create existence, we will create happiness and pick out how lots higher our lives can get!
Best when we are able to be given that life is best as it's miles, and that our lives are the sum general of the whole lot that has occurred as much as this second, can we take delivery of the pleasure and the happiness we deserve.
Insurance
Reply


Forum Jump:

User Panel Messages

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