Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python game CLI

Tags:

python

I was trying to make 20 x 2 is a game played by a human player with a computer. It’s a simple board game which requires some dice to play. I have tried human and computer but want to do this, so not sure what code I am doing wrong. any help highly appreciated

import random
import datetime

# initialize the game board
board = [['-' for _ in range(20)] for _ in range(2)]
board[0][0] = 'X'  # human player
board[1][0] = 'X'  # computer

# initialize variables
turn = 1  # human player goes first
human_pos = 0
computer_pos = 0
human_moves = 0
computer_moves = 0
human_hits = 0
computer_hits = 0

# function to print the game board
def print_board():
    print('+----' * 20 + '+')
    for row in range(2):
        for col in range(20):
            print('|', board[row][col], ' ', end='')
        print('|')
        print('+----' * 20 + '+')

# function to roll the dice
def roll_dice():
    return random.randint(1, 6)

# function to move the player's pawn
def move_pawn(player, steps):
    global human_pos, computer_pos
    if player == 'human':
        pos = human_pos
        row = 0
    else:
        pos = computer_pos
        row = 1
    board[row][pos] = '-'
    pos += int(steps/2)
    if pos >= 20:
        pos = 20
    if player == 'human':
        human_pos = pos
    else:
        computer_pos = pos
    if board[row][pos] == 'X':
        pos = 0
        board[row][pos] = 'X'
        if player == 'human':
            human_hits += 1
        else:
            computer_hits += 1
    else:
        board[row][pos] = 'X'

# function to check if a player has won
def check_win(player):
    if player == 'human':
        pos = human_pos
    else:
        pos = computer_pos
    if pos >= 20:
        return True
    else:
        return False

# main game loop
while True:
    print_board()
    if turn == 1:
        input('Press Enter to roll the dice')
        dice = roll_dice()
        print('You rolled a', dice)
        if dice == 6:
            move_pawn('human', dice)
            print_board()
            input('Press Enter to start the game')
            turn = 2
        else:
            print('You need to roll a 6 to start the game')
    else:
        dice = roll_dice()
        print('Computer rolled a', dice)
        if dice == 6:
            move_pawn('computer', dice)
            print_board()
            input('Press Enter to start the game')
            turn = 1
        else:
            move_pawn('computer', dice)
            print_board()
            if check_win('computer'):
                print('Computer wins!')
                break
            turn = 1
            input('Press Enter to continue')

    if check_win('human'):
        print('You win!')
        break

# count the number of moves and hits for each player
human_moves = human_pos + human_hits
computer_moves = computer_pos + computer_hits

# save the game session to a text file
date_time = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M')
filename = date_time + '.txt'
with open(filename, 'w') as f:
    f.write('Human\n')
    f.write('Total moves: ' + str(human_moves) + '\n')
    f.write
Traceback (most recent call last):
  File "c:\Users\abiruk\Downloads\main.py", line 77, in <module>
    move_pawn('human', dice)
  File "c:\Users\abiruk\Downloads\main.py", line 48, in move_pawn
    if board[row][pos] == 'X':
IndexError: list index out of range

I have tried human and computer but want to do this, so not sure what code I am doing wrong. any help highly appreciated

like image 457
abhiruk prashan Avatar asked Sep 16 '25 21:09

abhiruk prashan


1 Answers

The problem is that you're taking board[row][20], while board[row] only contains 0 - 19. This is because the first element of a list is accessed as my_list[0], the second as my_list[1], and thus the 20th as my_list[19]

There are some other things, so from the start:

  • I would define board as [['-']*20]*2, since it's smaller and easier to read than [['-' for _ in range(20)] for _ in range(2)]. The problem is, that they're referencing to the same '-'. We still have to add one to solve the IndexError though:
board = [['-' for _ in range(21)] for _ in range(2)]
  • In the move_pawn() function, you have to set globals for everything you edit. As you forgot some, here:
global board, human_pos, computer_pos, human_hits, computer_hits
  • In the move_pawn() function, if board[row][pos] == 'X': will never run, because when the pawn is moved forward, X will not be there. Instead, you have to check the other row. Also, the pos = 0 there is unnecessary, so I removed it.
if board[1 if row == 0 else 0][pos] == 'X':

Here's the entire code (with a bit of my formatting too):

import random
import datetime

# initialize the game board
board = [['-' for _ in range(21)] for _ in range(2)]
board[0][0] = 'X'  # human player
board[1][0] = 'X'  # computer

# initialize variables
turn = 1  # human player goes first

human_pos = 0
computer_pos = 0

human_moves = 0
computer_moves = 0

human_hits = 0
computer_hits = 0


def print_board() -> None:
    """function to print the game board"""
    print('+----' * 20 + '+')
    for row in range(2):
        for col in range(20):
            print('|', board[row][col], ' ', end='')
        print('|')
        print('+----' * 20 + '+')

    return None


def roll_dice() -> int:
    """function to roll the dice"""
    return random.randint(1, 6)


def move_pawn(player: str, steps: int) -> None:
    """function to move the player's pawn"""
    global board, human_pos, computer_pos, human_hits, computer_hits

    # Get the position
    if player == 'human':
        pos = human_pos
        row = 0
    else:
        pos = computer_pos
        row = 1
    board[row][pos] = '-'
    pos += int(steps/2)

    # Set pos to 20 if it's above
    if pos >= 20:
        pos = 20

    # Set the global pos
    if player == 'human':
        human_pos = pos
    else:
        computer_pos = pos

    # Check for the position on the other row:
    if board[1 if row == 0 else 0][pos] == 'X':
        board[row][pos] = 'X'

        if player == 'human':
            human_hits += 1
        else:
            computer_hits += 1
    else:
        board[row][pos] = 'X'

    return None


def check_win(player: str) -> bool:
    """function to check if a player has won"""
    if player == 'human':
        pos = human_pos
    else:
        pos = computer_pos
    if pos >= 20:
        return True
    else:
        return False


# main game loop
while True:
    print_board()
    if turn == 1:
        input('Press Enter to roll the dice')
        dice = roll_dice()
        print('You rolled a', dice)
        if dice == 6:
            move_pawn('human', dice)
            print_board()
            input('Press Enter to start the game')
            turn = 2
        else:
            print('You need to roll a 6 to start the game')
    else:
        dice = roll_dice()
        print('Computer rolled a', dice)
        if dice == 6:
            move_pawn('computer', dice)
            print_board()
            input('Press Enter to start the game')
            turn = 1
        else:
            move_pawn('computer', dice)
            print_board()
            if check_win('computer'):
                print('Computer wins!')
                break
            turn = 1
            input('Press Enter to continue')

    if check_win('human'):
        print('You win!')
        break

# count the number of moves and hits for each player
human_moves = human_pos + human_hits
computer_moves = computer_pos + computer_hits

# save the game session to a text file
date_time = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M')
filename = date_time + '.txt'
with open(filename, 'w') as f:
    f.write('Human\n')
    f.write('Total moves: ' + str(human_moves) + '\n')

like image 149
tygo Avatar answered Sep 19 '25 12:09

tygo