43zombiegit
43zombiegit

Reputation: 127

Shutting down pygame without using the mouse

I have made a basic tic-tac-toe game where I have 2 agents playing randomly. I want the game to run 10000's of times. I can do this at the moment but the instance only resets after I press the close button on the pygame window. Instead I want the window to either continually close and open again or have the window stay open constantly with a reset of the game board etc - both are fine. Here is the code:

import pygame
import numpy as np
import random
import time
import sys

def get_position(mouseX, mouseY):
    if mouseX <= width/3:
        col = 0
    elif mouseX <= 2*width/3:
        col = 1
    else:
        col = 2

    if mouseY <= height/3:
        row = 0
    elif mouseY <= 2*height/3:
        row = 1
    else:
        row = 2

    return (row, col)
def show_board(input, board):
    input.blit(board, (0,0))
    pygame.display.flip()

def initialise_board(input):
    background = pygame.Surface(input.get_size())
    background = background.convert()
    background.fill((250, 250, 250))
    pygame.draw.line(background, (0, 0, 0), (width / 3, 0), (width / 3, height), 2)
    pygame.draw.line(background, (0, 0, 0), (2 * width / 3, 0), (2 * width / 3, height), 2)
    pygame.draw.line(background, (0, 0, 0), (0, height / 3), (width, height / 3), 2)
    pygame.draw.line(background, (0, 0, 0), (0, 2 * height / 3), (width, 2 * height / 3), 2)
    input.blit(background, (0, 0))
    pygame.display.flip()
    return background

def check_board(row, col, array_board):
    if array_board[row][col] != 0:
        return False
    else:
        return True


#def get_mouse():
#    (mouseX, mouseY) = pygame.mouse.get_pos()
#    (row, col) = get_position(mouseX, mouseY)
#    return (row, col)

def check_win(array_board):
    global winner
    for row in range(3):
        if array_board[row][0] == array_board[row][1] == array_board[row][2] != 0:
            winner = array_board[row][0]
            pygame.draw.line(board, (0, 0, 0), (75, (row*round(height/3) + 150)), (825, (row*round(height/3) + 150)), 3)
            break
    for col in range(3):
        if array_board[0][col] == array_board[1][col] == array_board[2][col] != 0:
            winner = array_board[col][0]
            pygame.draw.line(board, (0, 0, 0), (col*round(width/3) + 150, 75), (col*round(width/3)+ 150, 825), 3)
            break

    if array_board[0][0] == array_board[1][1] == array_board[2][2] != 0:
        winner = array_board[0][0]
        pygame.draw.line(board, (0, 0, 0,), (75, 75), (825, 825), 3)
    if array_board[0][2] == array_board[1][1] == array_board[2][0] != 0:
        winner = array_board[0][2]
        pygame.draw.line(board, (0,0,0), (825, 75), (75, 825), 3)
    return winner

def click_board(array_board):
    global team
    (row, col) = get_position(random.randint(1,900), random.randint(1,900))

    centerX = (col * round(width/3)) + 150
    centerY = (row * round(height/3)) + 150
    if team == 2 and check_board(row, col, array_board):
        pygame.draw.circle(board, (0, 0, 0), np.round((centerX, centerY)), round(width/12), 2)
        team = 1
        array_board[row][col] = 2
    elif team == 1 and check_board(row, col, array_board):
        pygame.draw.line(board, (0,0,0), (centerX - width/15, centerY - height/15), (centerX + width/15, centerY + height/15), 2)
        pygame.draw.line(board, (0,0,0), (centerX + width/15, centerY - height/15), (centerX - width/15, centerY + height/15), 2)
        team = 2
        array_board[row][col] = 1


def game(array_board, board):
    global winner, xwins, owins
    winner = check_win(array_board)
    if winner == 0 and team == 1:
        message = "X's turn"
    elif winner == 0 and team == 2:
        message = "O's turn"
    elif winner != 0 and team == 2:
        message = "X wins!"
        xwins += 1
    elif winner != 0 and team == 1:
        message = "O wins!"
        owins += 1

    font = pygame.font.Font(None, 24)
    text = font.render(message, 1, (10,10,10))
    board.fill((250,250,250), (width/2 - 20, 50, width/2 + 20, 50))
    board.blit(text, (width/2,50))

xwins = 0
owins = 0

for i in range(10):
    pygame.init()
    width = 900
    height = 900
    input = pygame.display.set_mode((width,height))
    pygame.display.set_caption('Tic-Tac-Toe')
    array_board = np.zeros([3,3])
    winner = 0
    team = 1 #team 1 is X, team 2 is O
    board = initialise_board(input)



    running = True
    while running:
        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
            #elif event.type == pygame.MOUSEBUTTONDOWN and winner == 0:
        if winner == 0:
            print(winner)
            game(array_board, board)
            show_board(input, board)
            check_win(array_board)
            click_board(array_board)
            time.sleep(0.1)

    pygame.display.quit()
    pygame.quit()

Upvotes: 2

Views: 83

Answers (1)

Rabbid76
Rabbid76

Reputation: 210948

There are 2 conditions which end the game:

  • either the winner is set (winner != 0)
  • or all the fields on the playground are occupied
    (np.array(np.where(array_board == 0)).size == 0)

All you have to do is to implement the else case in your application and reset all the game states and redraw the empty playground.
Additionally you can count the games and break the loop after 10000 games. The for-loop (for i in range(10):) is not need any more.

no_of_games = 0
running = True
while running:
    for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
    
    end_of_game = winner != 0 or np.array(np.where(array_board == 0)).size == 0
    if not end_of_game:
        print(winner)
        game(array_board, board)
        show_board(input, board)
        check_win(array_board)
        click_board(array_board)
        time.sleep(0.1)
    else:
        array_board = np.zeros([3,3])
        team = 1
        winner = 0
        time.sleep(1)
        board = initialise_board(input)
        no_of_games += 1

    if no_of_games >= 10000:
        break

pygame.display.quit()
pygame.quit()

Upvotes: 2

Related Questions