Python Forum

Full Version: How to play against the computer
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have a fully functioning 4 in a row game, but the code I have written only allows for human player vs human player game, how would I go about programing a opponent for a human vs computer. in the future I want to incorporate levels of difficulty so I don't want a method that would limit me on that front. Any ideas would really be appreciated, thanks?
The simple solution would make the computer impossible to beat as it would calculate all the possible future positions based on where the human player played and where the AI should play to either win or at least tie. Then you would just dumb it down for easier difficulties. That would give you starting position for how to program the AI.
The standard algorithm for choosing the best move in games like this is the minimax algorithm, which isn't hugely complicated to implement.

One important aspect of software development is about how easy is it to make changes to a codebase to add new features or modify existing ones. You haven't shown the application, so it's impossible to say how easy or difficult the design makes adding that new functionality.
How hard would this be to make vs the computer:

import numpy as np
import pygame
import system as sys
import math
import time

BLUE = (0,0,255)
RED = (255,0,0)
YELLOW = (255,255,0) 
BLACK = (0,0,0)
ROW_COUNT = 6
COLUMN_COUNT = 7

def Zero_the_board():
    board = np.zeros((ROW_COUNT,COLUMN_COUNT))
    return board

def drop_piece(board, row, col, piece):
    board[row][col] = piece
    
def location_validation(board, col):
    return board[(ROW_COUNT-1)][col] == 0

def get_next_open_row(board, col):
    for r in range(ROW_COUNT):
        if board[r][col] == 0:
            return r

def winning_move_check(board, piece):
    #check all locations
    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 verticle locations
    for c in range(COLUMN_COUNT-3):
            for r in range(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(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 for negativly sloped diagonal locations
    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 display_the_board(board):
    #backround
    for c in range(COLUMN_COUNT):
        for r in range (ROW_COUNT):
            pygame.draw.rect(screen, BLUE, (c*SQUARESIZE, r*SQUARESIZE+SQUARESIZE, SQUARESIZE, SQUARESIZE))
            pygame.draw.circle(screen, BLACK, (int(c*SQUARESIZE+SQUARESIZE/2), int(r*SQUARESIZE+SQUARESIZE+SQUARESIZE/2)), RADIUS)
    #counters
    for c in range(COLUMN_COUNT):
        for r in range(ROW_COUNT):
            if board[r][c] == 1:
                pygame.draw.circle(screen, RED, (int(c*SQUARESIZE+SQUARESIZE/2), height-int(r*SQUARESIZE+SQUARESIZE/2)), RADIUS)
            elif board[r][c] == 2:
                pygame.draw.circle(screen, YELLOW, (int(c*SQUARESIZE+SQUARESIZE/2), height-int(r*SQUARESIZE+SQUARESIZE/2)), RADIUS)
    pygame.display.update()
    
board = Zero_the_board()
game_over = False
turn = 0

#pygame initialisation
pygame.init()

SQUARESIZE = 100
width = COLUMN_COUNT * SQUARESIZE
height = (ROW_COUNT+1) * SQUARESIZE

RADIUS = int(SQUARESIZE/2 - 5)

size = (width, height)

screen = pygame.display.set_mode(size)
display_the_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, SQUARESIZE))
            posx = event.pos[0]
            if turn == 0:
                pygame.draw.circle(screen, RED, (posx, int(SQUARESIZE/2)), RADIUS)
            else:
                pygame.draw.circle(screen, YELLOW, (posx, int(SQUARESIZE/2)), RADIUS)
            pygame.display.update()
        if event.type == pygame.MOUSEBUTTONDOWN:
            #player 1 input
            if turn == 0:
                posx = event.pos[0]
                col = int(math.floor(posx/SQUARESIZE))
                if location_validation(board, col):
                    row = get_next_open_row(board, col)
                    drop_piece(board, row, col, 1)
                    if winning_move_check(board, 1):
                        pygame.draw.rect(screen, BLACK, (0,0, width, SQUARESIZE))
                        label = MyFont.render("Player 1 Wins!", 1, RED)
                        screen.blit(label, (40,10))
                        game_over = True
            else:
                #player 2 input
                posx = event.pos[0]
                col = int(math.floor(posx/SQUARESIZE))
                if location_validation(board, col):
                    row = get_next_open_row(board, col)
                    drop_piece(board, row, col, 2)
                    if winning_move_check(board, 2):
                        pygame.draw.rect(screen, BLACK, (0,0, width, SQUARESIZE))
                        label = MyFont.render("Player 2 Wins ", 1, YELLOW)
                        screen.blit(label, (40,10))
                        game_over = True
            #player altinator
            turn = turn + 1
            turn = turn % 2
            display_the_board(board)

            if game_over:
                pygame.time.wait(3000)
The code looks familiar to me.
If you watched Keith Gallis youtube videos
he made one additional one implementing minimax with alphabeta pruning.