Click here to Skip to main content
15,881,877 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am writing a program similar to peg solitaire. I can not get it to work properly and I have attached all the code that I have so far. Any help/advice is appreciated.

The outline of the game is to have the player pick the amount of columns and rows they would like to start with. They then have to choose a free space. After declaring the rows, columns, and free space, the player must choose a 'peg' (in this case an 'o'), by choosing which row and column the peg is located in that they want to move. To move a peg, they must jump over only ONE peg, in any direction (over, under, left, right, or diagonal) and the choosen peg must land in an empty space. The peg that was "jumped" over is then to be removed. But the player is not allowed to jump over multiple pegs. The game is considered over when there are no more possible moves. Then to determine the players winning status, when two or less pegs remain on the board, the message "You're a genius!" should appear. When three or four pegs remain, the message "There have been better. But not many." should appear. When five or six pegs remain, the message "<# of pegs> pegs are left. Better luck next time!" should appear. When 7 or more pegs remain, the message "Better redeem yourself." should appear.

1. How can I determine if the game is over in the def game_over method?
2. How can I print the final messages from def final_messages?
3. How can I determine if a move is allowed and not allowed in the def legal_move method?
4. How can I make the make_move function work?

What I have tried:

import string
import numpy as np

class Peggame:

    def __init__(self, rows, columns, empty_row, empty_col):
        self.board = np.full((rows, columns), True)
        self.board[empty_row][empty_col] = False
        self.pegs_left = rows * columns - 1
        

    def __str__(self):
        answer = "   "
        for column in range(self.board.shape[1]):
            answer += " " + str(column + 1) + "  "
        answer += "\n"
        answer += self.separator()
        for row in range(self.board.shape[0]):
            answer += str(row + 1) + " |"
            for col in range(self.board.shape[1]):
                if self.board[row][col]:
                    answer += " o |"
                else:
                    answer += "   |"
            answer += "\n"
            answer += self.separator()
        return answer
    

    def separator(self):
        answer = "  +"
        for _ in range(self.board.shape[1]):
            answer += "---+"
        answer += "\n"
        return answer


    def legal_move(self, row_start, col_start, row_end, col_end):
        if  self.board[row_start][col_start] == False:
            return False
        if self.board[row_end][col_end] == False:
            return False
        horiztonal_movement = row_start == row_end
        vertical_movement = col_start == col_end
        if (horizontal_movement and vertical_movement) or (not horizontal_movement and not vertical_movement):
            return True
        
    def game_over(self):
        is_game_over = None
        if self.pegs_left <= 2:
            is_game_over = True
        elif self.pegs_left <= 4:
            is_game_over =  True
        elif self.pegs_left <= 6:
            is_game_over =  True
        elif self.pegs_left <= 1:
            is_game_over =  True
        else:
            if_game_over = False
        return(is_game_over)
               
    def final_message(self):
        if self.pegs_left <= 2:
            print("You're a genius!")
        elif self.pegs_left <= 4:
            print("There have been better. But not many.")
        elif self.pegs_left <= 6:
            print(str(self.pegs_left) + "pegs are left. Better luck next time!")
        else:
            print("Better redeem yourself") 
            
    def make_move(self, row_start, col_start, row_end, col_end):
        self.board[row_start][col_start] = False
        self.board[row_end][col_end] = True
        self.pegs_left -= 1
        
        if row_start == row_end:
            if col_start < col_end:
                self.board[row_end][col_end -1]  = False
            else:
                self.board[row_end][col_end + 1] = False
                
        if col_start == col_end:
            if row_start < row_end:
                self.board[row_end -1][col_end] = False
            else:
                self.board[row_end + 1][col_end] = False
               

      

def get_choice(low, high, message):
    message += " [" + str(low) + " - " + str(high) + "]: "
    legal_choice = False
    while not legal_choice:
        legal_choice = True
        answer = input(message)
        for character in answer:
            if character not in string.digits:
                legal_choice = False
                print("That is not a number, try again.")
                break 
        if legal_choice:
            answer = int(answer)
            if (answer < low) or (answer > high):
                legal_choice = False
                print("That is not a valid choice, try again.")
    return answer

def main():
    print("Welcome to Peg Solitaire!")
    print("-----------------------------------\n")
    
    rows = get_choice(1, 9, "Enter the number of rows")
    columns = get_choice(1, 9, "Enter the number of columns")
    row = get_choice(1, rows, "Enter the empty space row") - 1
    column = get_choice(1, columns, "Enter empty space column") - 1   
    game = Peggame(rows, columns, row, column)
    print()

    print(game)
    while (not game.game_over()):
        row_start = get_choice(1, rows, "Enter the row of the peg to move") - 1
        col_start = get_choice(1, columns, "Enter the column of the peg to move") - 1
        row_end = get_choice(1, rows, "Enter the row where the peg lands") - 1
        col_end = get_choice(1, columns, "Enter the column where the peg lands") - 1
        if game.legal_move(row_start, col_start, row_end, col_end):
            game.make_move(row_start, col_start, row_end, col_end)
        else:
            print("Sorry.  That move is not allowed.")
        print()
        print(game)

    game.final_message()



main()
Posted
Updated 3-Dec-21 20:11pm
v2

1 solution

Start by thinking about how you would do in manually: how do you decide if a move will be allowed when you play the game in the real world?
Simple: you look beside teh peg you want to move, and check there is a peg there, and that where the peg is to go is empty or not!

So do that in your code: for each direction, check if there is a peg in that direction, and a space in teh location immediately after the that peg. If both conditions are met, that is a legal move. If it isn't, you can't move there.

I would change the idea of the legal_move method to take an (x, y) location and a direction instead of two locations: that way it can check for the edges of the board as well - it the piece you want to move is at or close to the board edge, you can't move there, but there isn't necessarily a "coordinate" to check!

Get that working first, then start thinking about the rest - it's quite possible that getting that working will make the rest of it easier to develop.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900