diff --git a/Binary_tree/__pycache__/node.cpython-39.pyc b/Binary_tree/__pycache__/node.cpython-39.pyc index 78df13b1..1eaf6874 100644 Binary files a/Binary_tree/__pycache__/node.cpython-39.pyc and b/Binary_tree/__pycache__/node.cpython-39.pyc differ diff --git a/Binary_tree/__pycache__/tree.cpython-39.pyc b/Binary_tree/__pycache__/tree.cpython-39.pyc index ccc7e615..6313811e 100644 Binary files a/Binary_tree/__pycache__/tree.cpython-39.pyc and b/Binary_tree/__pycache__/tree.cpython-39.pyc differ diff --git a/Caesar_Cipher/Caesar_cipher.py b/Caesar_Cipher/Caesar_cipher.py index ac514ef3..5b6bba39 100644 --- a/Caesar_Cipher/Caesar_cipher.py +++ b/Caesar_Cipher/Caesar_cipher.py @@ -1,8 +1,26 @@ -class main: - def __init__(self,key:dict) -> None: +class main: + """ + The Main class provides functionality for encrypting and decrypting strings using a simple substitution cipher. + + Attributes: + key (dict): A dictionary mapping each letter of the alphabet to its corresponding encrypted letter. + blank_string (str): The string input by the user to be encrypted. + decrypted_string (str): The string that results from the encryption of the blank_string. + """ + def __init__(self, key: dict) -> None: + """ + Initializes the Main class with the given key for the substitution cipher. + + Parameters: + key (dict): A dictionary mapping each letter of the alphabet to its corresponding encrypted letter. + """ self.key = key - def get_input(self) -> None: + def get_input(self) -> None: + """ + Prompts the user to enter a string to be encrypted, validates the input, and converts it to lowercase. + Only alphabetical input is accepted, if the input is invalid, the user is prompted to try again. + """ while True: blank_string = str(input("Enter string to decrypt: ")) if blank_string.isalpha(): @@ -14,9 +32,15 @@ def get_input(self) -> None: continue def encrypt_string(self) -> str: + """ + Encrypts the user-provided string using the substitution cipher defined by the key. + + Returns: + str:The encrypted string. + """ output = "" for c in self.blank_string: - for k,v in self.key.items(): + for k, v in self.key.items(): if k == c: output += v else: @@ -25,6 +49,15 @@ def encrypt_string(self) -> str: return(output) def decrypt_string(self, string: str) -> str: + """ + Decrypts a given string using the substitution cipher defined by the key. + + Parameters: + string (str): The string to be decrypted. + + Returns: + str: The decrypted string, or the original blank_string if the input string is empty. + """ output = "" string = string.lower() string = string.strip() @@ -32,14 +65,17 @@ def decrypt_string(self, string: str) -> str: return(self.blank_string) else: for c in string: - for k,v in self.key.items(): + for k, v in self.key.items(): if v == c: output += k return(output) + if __name__ == "__main__": - key ={"a": "d", "b": "e", "c": "f", "d": "g", "e": "h", "f": "i", "g": "j", "h": "k", "i": "l", "j": "m", "k": "n", "l": "o", "m": "p", "n": "q", "o": "r", "p": "s", "q": "t", "r": "u", "s": "v", "t": "w", "u": "x", "v": "y", "w": "z", "x": "a", "y": "b", "z": "c"} + key = {"a": "d", "b": "e", "c": "f", "d": "g", "e": "h", "f": "i", "g": "j", "h": "k", "i": "l", "j": "m", "k": "n", + "l": "o", "m": "p", "n": "q", "o": "r", "p": "s", "q": "t", "r": "u", "s": "v", "t": "w", "u": "x", "v": "y", + "w": "z", "x": "a", "y": "b", "z": "c"} main = main(key=key) main.get_input() print(main.encrypt_string()) diff --git a/Caterpillar_Game/Caterpillar.py b/Caterpillar_Game/Caterpillar.py deleted file mode 100644 index 4afc8538..00000000 --- a/Caterpillar_Game/Caterpillar.py +++ /dev/null @@ -1,113 +0,0 @@ -import turtle as t -import random as rd - -t.bgcolor('yellow') - -caterpillar = t.Turtle() -caterpillar.shape('square') -caterpillar.speed(0) -caterpillar.penup() -caterpillar.hideturtle() - -leaf = t.Turtle() -leaf_shape = ((0,0),(14,2),(18,6),(20,20),(6,18),(2,14)) -t.register_shape('leaf', leaf_shape) -leaf.shape('leaf') -leaf.color('green') -leaf.penup() -leaf.hideturtle() -leaf.speed() - -game_started = False -text_turtle = False -text_turtle = t.Turtle() -text_turtle.write('Press SPACE to start', align='center', font=('Arial', 18, 'bold')) -text_turtle.hideturtle() - -score_turtle = t.Turtle() -score_turtle.hideturtle() -score_turtle.speed(0) - -def outside_window(): - left_wall = -t.window_width()/2 - right_Wall = t.window_width()/2 - top_wall = t.window_height()/2 - bottom_wall = -t.window_height()/2 - (x,y) = caterpillar.pos() - outside = x < left_wall or x > right_Wall or y > top_wall or y < bottom_wall - return outside - -def game_over(): - caterpillar.color('yellow') - leaf.color('yellow') - t.penup() - t.hideturtle() - t.write('GAME OVER !', align='center', font=('Arial', 30, 'normal') ) - t.onkey(start_game,'space') - -def display_score(current_score): - score_turtle.clear() - score_turtle.penup() - x = (t.window_width()/2) - 70 - y = (t.window_height()/2) - 70 - score_turtle.setpos(x,y) - score_turtle.write(str(current_score), align='right', font=('Arial', 40, 'bold')) - -def place_leaf(): - leaf.hideturtle() - leaf.setx(rd.randint(-200,200)) - leaf.sety(rd.randint(-200,200)) - leaf.showturtle() - -def start_game(): - global game_started - if game_started: - return - game_started = True - - score = 0 - text_turtle.clear() - - caterpillar_speed = 2 - caterpillar_length = 3 - caterpillar.shapesize(1,caterpillar_length,1) - caterpillar.showturtle() - display_score(score) - place_leaf() - - while True: - caterpillar.forward(caterpillar_speed) - if caterpillar.distance(leaf) < 20: - place_leaf() - caterpillar_length = caterpillar_length + 1 - caterpillar.shapesize(1,caterpillar_length,1) - caterpillar_speed = caterpillar_speed + 1 - score = score + 10 - display_score(score) - if outside_window(): - game_over() - break - -def move_up(): - caterpillar.setheading(90) - -def move_down(): - caterpillar.setheading(270) - -def move_left(): - caterpillar.setheading(180) - -def move_right(): - caterpillar.setheading(0) - -def restart_game(): - start_game() - -t.onkey(start_game,'space') -t.onkey(restart_game,'Up') -t.onkey(move_up,'Up') -t.onkey(move_right,'Right') -t.onkey(move_down,'Down') -t.onkey(move_left,'Left') -t.listen() -t.mainloop() diff --git a/Caterpillar_Game/__pycache__/caterpillarGame.cpython-39.pyc b/Caterpillar_Game/__pycache__/caterpillarGame.cpython-39.pyc new file mode 100644 index 00000000..891afd4a Binary files /dev/null and b/Caterpillar_Game/__pycache__/caterpillarGame.cpython-39.pyc differ diff --git a/Caterpillar_Game/__pycache__/caterpillar_test.cpython-39.pyc b/Caterpillar_Game/__pycache__/caterpillar_test.cpython-39.pyc new file mode 100644 index 00000000..a3b001f6 Binary files /dev/null and b/Caterpillar_Game/__pycache__/caterpillar_test.cpython-39.pyc differ diff --git a/Caterpillar_Game/__pycache__/gameDesign.cpython-39.pyc b/Caterpillar_Game/__pycache__/gameDesign.cpython-39.pyc new file mode 100644 index 00000000..467ef74c Binary files /dev/null and b/Caterpillar_Game/__pycache__/gameDesign.cpython-39.pyc differ diff --git a/Caterpillar_Game/caterpillarGame.py b/Caterpillar_Game/caterpillarGame.py new file mode 100644 index 00000000..8a9dc4c2 --- /dev/null +++ b/Caterpillar_Game/caterpillarGame.py @@ -0,0 +1,182 @@ +import turtle as t +from gameDesign import GameDesign + +class CaterpillarGame: + """ + The CaterpillarGame is a game where the player controls a caterpillar to eat + leaves, and grow in length, while avoiding the window boundaries. + + Attributes: + design (GameDesign): An instance of the GameDesign class to handle game visuals. + game_started (bool): A flag indicating if the game has started. + score (int): The score of the player + caterpillar_speed (int): the speed of the caterpillar + caterpillar_length (int): the length of the caterpillar + retry_button (turtle.Turtle): A turtle to represent the retry button. + """ + def __init__(self): + """ + Initializes the game by setting up the initial game state and binding keyboard keys. + """ + self.design = GameDesign() + self.game_started = False + self.score = 0 + self.caterpillar_speed = 2 + self.caterpillar_length = 3 + + self.design.write_text('Press Space to start', (0, 0), ('Arial', 18, 'bold')) + self.bind_keys() + self.create_retry_button() + t.tracer(0) + + def bind_keys(self): + """ + Binds the arrow keys for controlling the caterpillar and the space key to start the game. + """ + t.onkey(self.start_game, 'space') + t.onkey(self.move_up, 'Up') + t.onkey(self.move_right, 'Right') + t.onkey(self.move_down, 'Down') + t.onkey(self.move_left, 'Left') + t.listen() + + def create_retry_button(self): + """ + Creates the retry button. + """ + self.retry_button = t.Turtle() + self.retry_button.shape('square') + self.retry_button.color('blue') + self.retry_button.penup() + self.retry_button.hideturtle() + self.retry_button.goto(0, -50) + self.retry_button.onclick(self.start_game) + self.retry_button.write('Retry', align='center', font=('Arial', 18, 'bold')) + + def start_game(self, x=None, y=None): + """ + Start the game, resetting the score, caterpillar's speed, and length, and placing the first leaf. + """ + if self.game_started: + return + self.game_started = True + self.retry_button.clear() + self.retry_button.hideturtle() + self.reset_game() + self.run_game_loop() + + def reset_game(self): + """ + Resets the game to its initial state. + """ + self.score = 0 + self.design.text_turtle.clear() + self.design.score_turtle.clear() + self.clear_game_over_text() + + self.caterpillar_speed = 2 + self.caterpillar_length = 3 + self.design.caterpillar.color('black') + self.design.caterpillar.shapesize(1, self.caterpillar_length, 1) + self.design.caterpillar.goto(0, 0) + self.design.caterpillar.setheading(0) + self.design.caterpillar.showturtle() + + self.design.leaf.color('green') + self.design.display_score(self.score) + self.design.place_leaf() + + def run_game_loop(self): + """ + Runs the main loop, moving the caterpillar, checking for collisions with leaves, + updating the score, and checking for game over conditions. + """ + if self.game_started: + self.design.caterpillar.forward(self.caterpillar_speed) + if self.design.caterpillar.distance(self.design.leaf) < 20: + self.design.place_leaf() + self.caterpillar_length += 1 + self.design.caterpillar.shapesize(1, self.caterpillar_length, 1) + self.caterpillar_speed += 1 + self.score += 10 + self.design.display_score(self.score) + if self.outside_window(): + self.game_over() + return + t.update() + t.ontimer(self.run_game_loop, 100) + + def outside_window(self): + """ + Checks if the caterpillar is outside the window boundaries. + + Returns: + bool: True if the caterpillar is outside the window, False otherwise. + """ + left_wall = -t.window_width() / 2 + right_wall = t.window_width() / 2 + top_wall = t.window_height() / 2 + bottom_wall = -t.window_height() / 2 + (x, y) = self.design.caterpillar.pos() + return x < left_wall or x > right_wall or y > top_wall or y < bottom_wall + + def game_over(self): + """ + Ends the game by changing the color of the caterpillar and leaf, and displaying 'Game Over' text. + """ + self.game_started = False + self.design.caterpillar.color('yellow') + self.design.leaf.color('yellow') + t.penup() + t.hideturtle() + t.write('Game Over!', align='center', font=('Arial', 30, 'normal')) + self.retry_button.showturtle() + self.retry_button.goto(0, -50) + self.retry_button.write('Retry', align='center', font=('Arial', 18, 'bold')) + + def clear_game_over_text(self): + """ + Clears the 'Game Over' Text. + """ + t.clear() + t.hideturtle() + + def move_up(self): + """ + Changes the caterpillar's directions to up. + """ + if self.design.caterpillar.heading() != 270: + self.design.caterpillar.setheading(90) + + def move_down(self): + """ + changes the caterpillar's direction to down. + """ + if self.design.caterpillar.heading() != 90: + self.design.caterpillar.setheading(270) + + def move_left(self): + """ + Changes the caterpillar's direction to left. + """ + if self.design.caterpillar.heading() != 0: + self.design.caterpillar.setheading(180) + + def move_right(self): + """ + Changes the caterpillar's direction to right. + """ + if self.design.caterpillar.heading() != 180: + self.design.caterpillar.setheading(0) + +if __name__ == '__main__': + game = CaterpillarGame() + t.mainloop() + + + + + + + + diff --git a/Caterpillar_Game/caterpillar_test.py b/Caterpillar_Game/caterpillar_test.py new file mode 100644 index 00000000..b9c01673 --- /dev/null +++ b/Caterpillar_Game/caterpillar_test.py @@ -0,0 +1,34 @@ +import unittest +from caterpillarGame import CaterpillarGame + + +class TestCaterpillarGame(unittest.TestCase): + + def setUp(self): + self.game = CaterpillarGame() + + def test_initial_state(self): + self.assertFalse(self.game.game_started) + self.assertEqual(self.game.score, 0) + self.assertEqual(self.game.caterpillar_speed, 2) + self.assertEqual(self.game.caterpillar_length, 3) + + def test_move_up(self): + self.game.move_up() + self.assertEqual(self.game.design.caterpillar.heading(), 90) + + def test_move_down(self): + self.game.move_down() + self.assertEqual(self.game.design.caterpillar.heading(), 270) + + def test_move_left(self): + self.game.move_left() + self.assertEqual(self.game.design.caterpillar.heading(), 180) + + def test_move_right(self): + self.game.move_right() + self.assertEqual(self.game.design.caterpillar.heading(), 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/Caterpillar_Game/gameDesign.py b/Caterpillar_Game/gameDesign.py new file mode 100644 index 00000000..cc13acd1 --- /dev/null +++ b/Caterpillar_Game/gameDesign.py @@ -0,0 +1,109 @@ +import turtle as t +import random as rd + +class GameDesign: + """ + The GameDesign class handle the setup and visual aspect of the caterpillar game, + including the screen, caterpillar, leaf, text and score display. + + Attributes: + caterpillar (turtle.Turtle): A turtle representing the caterpillar. + leaf (turtle.Turtle): The turtle representing the leaf. + text_turtle (turtle.Turtle): A turtle for displaying text messages. + score_turtle (turtle.Turtle): A turtle for displaying the score. + """ + def __init__(self): + """ + Initializes the GameDesign class. + """ + self.setup_screen() + self.setup_caterpillar() + self.setup_leaf() + self.setup_text_turtle() + self.setup_score_turtle() + + def setup_screen(self): + """ + Sets up the game screen + """ + t.bgcolor('yellow') + + def setup_caterpillar(self): + """ + Sets up the caterpillar turtle. + """ + self.caterpillar = t.Turtle() + self.caterpillar.shape('square') + self.caterpillar.speed(0) + self.caterpillar.penup() + self.caterpillar.hideturtle() + + def setup_leaf(self): + """ + Sets up the leaf turtle. + """ + self.leaf = t.Turtle() + leaf_shape = ((0, 0), (14, 2), (18, 6), (20, 20), (6, 18), (2, 14)) + t.register_shape('leaf', leaf_shape) + self.leaf.shape('leaf') + self.leaf.color('green') + self.leaf.penup() + self.leaf.hideturtle() + self.leaf.speed(0) + + def setup_text_turtle(self): + """ + Sets up the text turtle + """ + self.text_turtle = t.Turtle() + self.text_turtle.hideturtle() + + def setup_score_turtle(self): + """ + Sets up the score turtle + """ + self.score_turtle = t.Turtle() + self.score_turtle.hideturtle() + self.score_turtle.speed(0) + + def write_text(self, message, position, font): + """ + Writes the given text on the screen. + + Parameters: + message (str): The text to be displayed. + position (tuple): The (x, y) position to display the text. + font (tuple): The font properties for the text. + """ + self.text_turtle.clear() + self.text_turtle.penup() + self.text_turtle.goto(position) + self.text_turtle.write(message, align='center', font=font) + + def display_score(self, score): + """ + Displays the current score on the screen. + + Parameters: + score (int): The current score to be displayed. + """ + self.score_turtle.clear() + self.score_turtle.penup() + x = (t.window_width() / 2) - 70 + y = (t.window_height() / 2) - 70 + self.score_turtle.setpos(x, y) + self.score_turtle.write(str(score), align='right', font=('Arial', 40, 'bold')) + + def place_leaf(self): + """ + Places the leaf at a random position on the screen. + """ + self.leaf.hideturtle() + self.leaf.setx(rd.randint(-200, 200)) + self.leaf.sety(rd.randint(-200, 200)) + self.leaf.showturtle() + + + + + diff --git a/Chess_Game/ChessEngine.py b/Chess_Game/ChessEngine.py index 3355cc86..1ec6917e 100644 --- a/Chess_Game/ChessEngine.py +++ b/Chess_Game/ChessEngine.py @@ -1,8 +1,15 @@ +class GameState: + """ + Represents the state of a chess game, including the board, move history, + and current player turn. + """ -class GameState: - def __init__(self): - self.board = [ + """ + Initializes the game state with the starting board setup, move functions, + and game status indicators. + """ + self.board = [ ["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"], ["bp", "bp", "bp", "bp", "bp", "bp", "bp", "bp"], ["--", "--", "--", "--", "--", "--", "--", "--"], @@ -11,16 +18,22 @@ def __init__(self): ["--", "--", "--", "--", "--", "--", "--", "--"], ["wp", "wp", "wp", "wp", "wp", "wp", "wp", "wp"], ["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]] - self.moveFunctions = {'p': self.getPawnMoves, 'R': self.getRookMoves, 'N': self.getKnightMoves, - 'B': self.getBishopMoves, 'Q': self.getQueenMoves, 'K': self.getKingMoves} - self.whiteToMove = True, - self.moveLog = [] - self.whiteKingLocation = (7, 4) - self.blackKingLocation = (0, 4) - self.checkMate = False - self.staleMate = False + self.moveFunctions = {'p': self.getPawnMoves, 'R': self.getRookMoves, 'N': self.getKnightMoves, + 'B': self.getBishopMoves, 'Q': self.getQueenMoves, 'K': self.getKingMoves} + self.whiteToMove = True, + self.moveLog = [] + self.whiteKingLocation = (7, 4) + self.blackKingLocation = (0, 4) + self.checkMate = False + self.staleMate = False def makeMove(self, move): + """ + Executes a given move on the board, updates move log, and switches player turn. + + Args: + move (move): The move to be made,an instance of the move class. + """ self.board[move.startRow][move.startCol] = "--" self.board[move.endRow][move.endCol] = move.pieceMoved self.moveLog.append(move) @@ -35,6 +48,10 @@ def makeMove(self, move): def undoMove(self): + """ + Undoes the last move made,reverting the board to the previous state + and switching the player turn. + """ if len(self.moveLog) != 0: move = self.moveLog.pop() self.board[move.startRow][move.startCol] = move.pieceMoved @@ -44,10 +61,14 @@ def undoMove(self): self.whiteKingLocation = (move.startRow, move.startCol) if move.pieceMoved == "bK": self.blackKingLocation = (move.startRow, move.startCol) - """ - All move considering checks - """ + def getValidMoves(self): + """ + Returns a list of all valid moves, considering checks. + + Returns: + list: A list of valid moves. + """ moves = self.getAllPossibleMoves() for i in range(len(moves)-1, -1, -1): self.makeMove(moves[i]) @@ -68,12 +89,28 @@ def getValidMoves(self): return moves def inCheck(self): + """ + Checks if the current player is in checks. + + Returns: + bool: True if the current player is in check, False otherwise. + """ if self.whiteToMove: return self.squareUnderAttack(self.whiteKingLocation[0], self.whiteKingLocation[1]) else: return self.squareUnderAttack(self.blackKingLocation[0], self.blackKingLocation[1]) def squareUnderAttack(self, r, c): + """ + Determines if a specific square is under attack. + + Args: + r (int): The row of the square. + c (int): The column of the square. + + Returns: + bool: True if the square is under attack, False otherwise. + """ self.whiteToMove = not self.whiteToMove oppMoves = self.getAllPossibleMoves() self.whiteToMove = not self.whiteToMove @@ -82,13 +119,13 @@ def squareUnderAttack(self, r, c): return True return False - - - - """ - All move without considering checks - """ def getAllPossibleMoves(self): + """ + Returns a list of all possible moves without considering checks. + + Returns: + list: A list of all possible moves. + """ moves = [] for r in range(len(self.board)): for c in range(len(self.board[r])): @@ -100,6 +137,14 @@ def getAllPossibleMoves(self): def getPawnMoves(self, r, c, moves): + """ + Adds all possible pawn moves to the list of moves. + + Args: + r (int); The row of the pawn. + c (int): The column of the pawn. + moves (list): The list of moves to append to. + """ if self.whiteToMove: if self.board[r-1][c] == "--": moves.append(Move((r, c),(r-1, c), self.board)) @@ -125,6 +170,14 @@ def getPawnMoves(self, r, c, moves): moves.append(Move((r, c),(r+1, c+1), self.board)) def getRookMoves(self, r, c, moves): + """ + Adds all possible rook moves to the list of moves. + + Args: + r (int): The row of the rook. + c (int): The column of the rook. + moves (list): The list of moves to append to. + """ directions = ((-1, 0), (0, -1), (1, 0), (0, 1)) enemyColor = "b" if self.whiteToMove else "w" for d in directions: @@ -144,6 +197,14 @@ def getRookMoves(self, r, c, moves): break def getKnightMoves(self, r,c,moves): + """ + Adds all posible knight moves to the list of moves. + + Args: + r (int): The row of the knight. + c (int): The column of the knight. + moves (list): The list of moves to append to. + """ knightMoves = ((-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2,1)) allyColor = "w" if self.whiteToMove else "b" for m in knightMoves: @@ -155,6 +216,17 @@ def getKnightMoves(self, r,c,moves): moves.append(Move((r,c), (endRow, endCol), self.board)) def getBishopMoves(self, r,c,moves): + """ + Adds all possible bishop moves to the list moves. + + Args: + r (int): The row index of the bishop's starting position. + c (int): The column index of the bishop's starting position. + moves (list): A list to which the valid moves will be appended. + + Returns: + None + """ directions = ((-1, -1), (-1, 1), (1, -1), (1, 1)) enemyColor = "b" if self.whiteToMove else "w" for d in directions: @@ -174,10 +246,30 @@ def getBishopMoves(self, r,c,moves): break def getQueenMoves(self, r,c,moves): + """ + Adds all possible queen moves from the given position (r,c) on the board. + + This method combines the generation logic of rooks and bishops adding all + valid moves to the 'moves' list. + + Args: + r (int): The row index of the queen's starting position. + c (int): The column index of the queen's starting position. + moves (list): A list to witch the valid moves will be appended. + """ self.getRookMoves(r, c, moves) self.getBishopMoves(r, c, moves) def getKingMoves(self, r,c,moves): + """ + This method checks each possible move for the king and adds valid moves + to the 'moves' list. + + Args: + r (int): The row index of the king's starting position. + c (int): The column index of the king's starting position. + moves (int): A list to which the valid moves will be appended. + """ kingMoves = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1,1) ) allyColor = "w" if self.whiteToMove else "b" for i in range(8): @@ -188,6 +280,19 @@ def getKingMoves(self, r,c,moves): if endPiece[0] != allyColor: moves.append(Move((r,c), (endRow, endCol), self.board)) class Move(): + """ + This class represent a chess move. + + Attributes: + startRow (int): The starting row index of the move. + startCol (int): The starting column index of the move. + endRow (int): The ending row index of the move. + endCol (int): The ending column index of the move. + pieceMoved (str): The piece being moved. + pieceCaptured (str): The piece being captured (if any). + isPawnPromotion (bool): Whether the move is a pawn promotion. + moveID (int): A unique identifier for the move. + """ ranksToRow = {"1": 7, "2": 6, "3": 5, "4": 4, "5": 3, "6": 2, "7": 1, "8": 0} @@ -197,6 +302,14 @@ class Move(): colsToFiles = {v: k for k, v in filesToCols.items()} def __init__(self, startSq, endSq, board): + """ + Initializes a move object. + + Parameters: + startSq (tuple): A tuple (row, col) representing the starting square of the move. + endSq (tuple): A tuple (row, col) representing the ending square of the move. + board (list): The current state of the chess board. + """ self.startRow = startSq[0] self.startCol = startSq[1] self.endRow = endSq[0] @@ -209,14 +322,36 @@ def __init__(self, startSq, endSq, board): self.moveID = self.startRow * 1000 + self.startCol * 100 + self.endRow * 10 + self.endCol def __eq__(self, other): + """ + checks if two move objects are equal based on their moveID. + + Args: + other (move): Another move object to compare with. + """ if isinstance(other, Move): return self.moveID == other.moveID return False def getChessNotation(self): + """ + Returns the move in standard chess notation. + + Returns: + str: The move in chess notation + """ return self.getRankFile(self.startRow, self.startCol) + self.getRankFile(self.endRow, self.endCol) def getRankFile(self, r, c): + """ + Converts row and column indices to chess rank and file notation. + + Args: + r (int): The row index. + c (int): The column index. + + Returns: + str: The corresponding chess rank and file + """ return self.colsToFiles[c] + self.rowsToRanks[r] diff --git a/Chess_Game/ChessGame.py b/Chess_Game/ChessGame.py index 5a361913..2014120c 100644 --- a/Chess_Game/ChessGame.py +++ b/Chess_Game/ChessGame.py @@ -8,11 +8,20 @@ IMAGES = {} def loadImages(): + """ + Load chess piece images and scale them to the appropriate size. + """ pieces = ['wp', 'wR', 'wN', 'wB', 'wQ', 'wK', 'bp', 'bR', 'bN', 'bB', 'bQ', 'bK' ] for piece in pieces: IMAGES[piece] = p.transform.scale(p.image.load("images/" + piece + ".png"), (SQ_SIZE, SQ_SIZE)) def main(): + """ + Main function to run the chess game. + + This function initializes the game window, sets up the game state, handles user input, + updates the game state based on user actions, and renders the game state on the screen. + """ p.init() screen = p.display.set_mode((WIDTH, HEIGHT)) clock = p.time.Clock() @@ -87,6 +96,15 @@ def main(): p.display.flip() def highlightSquares(screen, gs, validMoves, sqSelected): + """ + Highlight the squares on the chessboard based on the selected piece and its valid moves. + + Args: + screen: The game screen surface. + gs (ChessEngine.GameState): The current game state. + validMoves (list): List of valid moves for the selected piece. + sqSelected (tuple): Tuple containing the coordinates of the selected square. + """ if sqSelected != (): r, c = sqSelected if gs.board[r][c][0] == ('w' if gs.whiteToMove else 'b'): @@ -100,11 +118,26 @@ def highlightSquares(screen, gs, validMoves, sqSelected): screen.blit(s, (SQ_SIZE*moves.endCol, SQ_SIZE*moves.endRow)) def drawGameState(screen, gs, validMoves, sqSelected): + """ + Draw the current state of the chess game on the screen. + + Args: + screen: The game screen surface. + gs (ChessEngine.GameState): The current game state. + validMoves (list): List of valid moves for the selected piece. + sqSelected (tuple): Tuple containing the coordinates of the selected square. + """ drawBoard(screen) highlightSquares(screen, gs, validMoves, sqSelected) drawPieces(screen, gs.board) def drawBoard(screen): + """ + Draw the chessboard on the screen. + + Args: + screen: The game screen surface. + """ global colors colors = [p.Color("white"), p.Color("grey")] for r in range(DIMENSIONS): @@ -113,6 +146,13 @@ def drawBoard(screen): p.draw.rect(screen, color, p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE)) def drawPieces(screen, board): + """ + Draw the chess pieces on the screen based on the current board state. + + Args: + screen: The game screen surface. + board (list): 2D list representing the class board state. + """ for r in range(DIMENSIONS): for c in range(DIMENSIONS): piece = board[r][c] @@ -120,6 +160,15 @@ def drawPieces(screen, board): screen.blit(IMAGES[piece], p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE)) def animatedMoves(move, screen,board, clock): + """ + Animate the movement of a chess piece on the screen. + + Args: + move (ChessEngine.Move): The move to animate. + screen: The game screen surface. + board (list): 2D list representing the chess board state. + clock: Pygame clock objects. + """ global colors dR = move.endRow - move.startRow dC = move.endCol - move.startCol @@ -140,6 +189,13 @@ def animatedMoves(move, screen,board, clock): clock.tick(60) def drawText(screen, text): + """ + Draw text on the screen + + Args: + screen: The game screen surface. + text (str): The text to be displayed. + """ font = p.font.SysFont("Helvitca", 32, True, False) textObject = font.render(text, True, p.Color('Gray')) textLocation = p.Rect(0, 0, WIDTH, HEIGHT).move(WIDTH/2 - textObject.get_width()/2, HEIGHT/2 - textObject.get_height()/2) diff --git a/Chess_Game/README.md b/Chess_Game/README.md index 9a91ca05..88989d7a 100644 --- a/Chess_Game/README.md +++ b/Chess_Game/README.md @@ -22,5 +22,52 @@ python ChessGame.py

![alt text] +## 🕹ī¸ Game Instruction + - Move Pieces: Click on a piece to select it and then click on the target square to move. + - Undo Moves: Press the 'z' key to undo the last move. + - Restart Game: Press the 'r' key to restart the game. + +## 🎮 Gameplay Features + - Two-Player Mode: Play with a friend locally. + - Valid Moves Highlighting: Highlight valid moves for the selected piece. + - Check and Checkmate Detection: The game detects check and checkmate situations. + - Stalemate Detection: The game detects stalemate situations. + +## 🧩 Classes and Methods + `GameState` + - Attributes: + - board: The current state of the chess board. + - moveFunctions: A dictionary of piece types and their respective move functions. + - whiteToMove: Boolean indicating if it's white's turn to move. + - moveLog: A log of all moves made during the game. + - whiteKingLocation, blackKingLocation: The current positions of the white and black kings. + - checkMate, staleMate: Booleans indicating if the game is in checkmate or stalemate. + + `Methods` + - __init__(): Initializes the game state with the starting board setup. + - makeMove(move): Executes a given move on the board. + - undoMove(): Undoes the last move made. + - getValidMoves(): Returns a list of all valid moves, considering checks. + - inCheck(): Checks if the current player is in check. + - squareUnderAttack(r, c); Determines if a specific square is under attack. + - getAllPossibleMoves(): Returns a list of all possible moves without considering checks. + - getPawnMoves(r, c, moves), getRookMoves(r, c, moves), getKnightMoves(r, c, moves), + getBishopMoves(r, c, moves), getQueenMoves(r, c, moves), getKingMoves(r, c, moves): Add all + possible moves for the respective pieces to the list of moves. + + `Move` + - Attributes: + - startRow, startCol: The starting position of the move. + - endRow, andCol: The ending position of the move. + - pieceMoved, pieceCaptured: The piece being moved and the piece being captured. + - isPawnPromotion: Whether the move is a pawn promotion. + - moveID: A unique identifier for the move. + + - Methods: + - __init__(startSq, endSq, board): Initializes a move object. + - __eq__(other): Checks if two move objects are equal based on their moveID. + - getChessNotation(): Returns the move in standard chess notation. + - getRankFile(r, c,): Converts row and column indicates to chess rank and file notation. + ## *Author Name* [Abhi Bhullar](https://github.com/userabhibhullar) \ No newline at end of file diff --git a/Dice_Rolling_Stimulator/README.md b/Dice_Rolling_Stimulator/README.md index b624ea66..239713e9 100644 --- a/Dice_Rolling_Stimulator/README.md +++ b/Dice_Rolling_Stimulator/README.md @@ -10,7 +10,8 @@ ## 🛠ī¸ Description -This is a simple dice stimulator made using Python. +This is a simple dice stimulator made using Python. It simulates rolling a dice and provides the option to roll again +or exit the game. ## ⚙ī¸ Languages or Frameworks Used @@ -24,6 +25,25 @@ Running the script is really simple! Just open a terminal in the folder where yo python dice_stimulator.py ``` +## 🎲 How to Play + - run the script in the terminal + - click enter + - type 'y' if you want to keep rolling the dice or 'x' to stop the game. + +## 🧩 Classes and Methods +`DiceSimulator` + - Attributes: + - dice_faces (dict): A dictionary that contains the faces of the dice as lists of strings. + + - Methods: + - __init__(): Initializes the 'DiceSimulator' with dice faces. + - roll_dice(): Rolls the dice and prints the corresponding face. + - int:The number rolled on the dice + - play_again(): Prompts the user to roll again or exit the game. + - roll_again: Indicates whether the user wants to roll again. + - exit_game: Indicates whether the user wants to exit the game. + - start(): Starts the dice rolling simulation. + ## đŸ“ē Demo

diff --git a/Dice_Rolling_Stimulator/dice_stimulator.py b/Dice_Rolling_Stimulator/dice_stimulator.py index 7fa65607..7a54f584 100644 --- a/Dice_Rolling_Stimulator/dice_stimulator.py +++ b/Dice_Rolling_Stimulator/dice_stimulator.py @@ -1,50 +1,105 @@ import random -print("This is a dice stimulator") -x = "y" -while x == "y": - number = random.randint(1,6) - - if number == 1: - print("===========") - print("| |") - print("| O |") - print("| |") - print("===========") - - if number == 2: - print("===========") - print("| |") - print("| O O |") - print("| |") - print("===========") - - if number == 3: - print("===========") - print("| O |") - print("| O |") - print("| O |") - print("===========") - - if number == 4: - print("===========") - print("| O O |") - print("| |") - print("| O O |") - print("===========") - - if number == 5: - print("===========") - print("| O O |") - print("| O |") - print("| O O |") - print("===========") - - if number == 6: - print("===========") - print("| O O |") - print("| O O |") - print("| O O |") - print("===========") - - x = input("Press y to roll again ") \ No newline at end of file +class DiceSimulator: + """ + A class to simulate rolling a dice. + + Attributes: + dice_faces (dict): A dictionary that contain the faces of the dice as lists of strings. + """ + def __init__(self): + """ + Initializes the DiceSimulator with dice faces. + """ + self.dice_faces = { + 1: [ + "===========", + "| |", + "| O |", + "| |", + "===========" + ], + 2: [ + "===========", + "| |", + "| O O |", + "| |", + "===========" + ], + 3: [ + "===========", + "| O |", + "| O |", + "| O |", + "===========" + ], + 4: [ + "===========", + "| O O |", + "| |", + "| O O |", + "===========" + ], + 5: [ + "===========", + "| O O |", + "| O |", + "| O O |", + "===========" + ], + 6: [ + "===========", + "| O O |", + "| O O |", + "| O O |", + "===========" + ] + } + + def roll_dice(self): + """ + Rolls the dice and prints the corresponding face. + + Returns: + int: The number rolled on the dice + """ + number = random.randint(1, 6) + dice_face = self.dice_faces[number] + for line in dice_face: + print(line) + return number + + def play_again(self): + """ + Prompts the user to roll again or exit the game. + + Returns: + roll_again (bool): Indicates whether the user wants to roll again. + exit_game (bool): Indicates whether the user wants to exit the game. + """ + choice = input("Type 'y' and enter if you want to roll again, or 'x' to exit: ").lower() + return choice == 'y', choice == 'x' + + def start(self): + """ + Starts the dice rolling simulation. + """ + print("This is a dice stimulator") + while True: + number = self.roll_dice() + roll_again, exit_game = self.play_again() + if exit_game: + print("Exiting the game...") + break + elif not roll_again: + print("Rolling stopped.") + break + +if __name__ == "__main__": + game = DiceSimulator() + game.start() + + + + +